10 | * https://github.com/minbox-projects/minbox-sequence
11 | *
12 | * @author 恒宇少年
13 | */
14 | public class MinBoxSequenceLogTraceIdGenerator implements LogTraceIdGenerator {
15 | private static final int DEFAULT_DATA_CENTER_ID = 1;
16 | private Sequence sequence;
17 |
18 | public MinBoxSequenceLogTraceIdGenerator() {
19 | this(DEFAULT_DATA_CENTER_ID);
20 | }
21 |
22 | public MinBoxSequenceLogTraceIdGenerator(int dataCenterId) {
23 | this.sequence = new Sequence(dataCenterId);
24 | }
25 |
26 | @Override
27 | public String createTraceId() throws MinBoxLoggingException {
28 | return String.valueOf(sequence.nextId());
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/minbox-logging-admin-ui/src/main/frontend/utils/d3.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014-2018 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import * as array from 'd3-array';
18 | import * as axis from 'd3-axis';
19 | import * as brush from 'd3-brush';
20 | import * as scale from 'd3-scale';
21 | import * as selection from 'd3-selection';
22 | import * as shape from 'd3-shape';
23 | import * as time from 'd3-time';
24 |
25 | export default {
26 | ...array,
27 | ...axis,
28 | ...brush,
29 | ...scale,
30 | ...selection,
31 | ...shape,
32 | ...time
33 | }
34 |
--------------------------------------------------------------------------------
/minbox-logging-admin-ui/src/main/frontend/sba-settings.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014-2019 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | //This is a Thymleaf template whill will be rendered by the backend
18 | var SBA = {
19 | uiSettings: /*[[${uiSettings}]]*/ {},
20 | user: /*[[${user}]]*/ null,
21 | extensions: [],
22 | csrf: {
23 | parameterName: /*[[${_csrf} ? ${_csrf.parameterName} : 'null']]*/ null,
24 | headerName: /*[[${_csrf} ? ${_csrf.headerName} : 'null']]*/ null
25 | },
26 | use: function (ext) {
27 | this.extensions.push(ext);
28 | }
29 | };
30 |
--------------------------------------------------------------------------------
/minbox-logging-admin-ui/src/main/frontend/login.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014-2018 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import '@/assets/css/base.scss';
18 | import i18n from './i18n'
19 |
20 | document.querySelectorAll('[data-i18n]')
21 | .forEach(t => {
22 | let [attribute, key] = t.getAttribute('data-i18n').split(':');
23 | if (!key) {
24 | key = attribute;
25 | attribute = undefined;
26 | }
27 |
28 | if (attribute) {
29 | t.setAttribute(attribute, i18n.t(key));
30 | } else {
31 | t.innerHTML = i18n.t(key);
32 | }
33 | });
34 |
--------------------------------------------------------------------------------
/minbox-logging-core/src/main/java/org/minbox/framework/logging/core/response/ReportResponse.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright [2019] [恒宇少年 - 于起宇]
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | */
17 |
18 | package org.minbox.framework.logging.core.response;
19 |
20 | import lombok.Data;
21 |
22 | /**
23 | * Report Request Log To Admin After Response Entity
24 | *
25 | * @author 恒宇少年
26 | */
27 | @Data
28 | public class ReportResponse {
29 |
30 | public static final String SUCCESS = "SUCCESS";
31 |
32 | public static final String ERROR = "ERROR";
33 |
34 | private String status;
35 | }
36 |
--------------------------------------------------------------------------------
/minbox-logging-core/src/main/java/org/minbox/framework/logging/core/ReportAway.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright [2019] [恒宇少年 - 于起宇]
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | */
17 |
18 | package org.minbox.framework.logging.core;
19 |
20 | import lombok.Getter;
21 |
22 | /**
23 | * Report Request Log To Admin Away
24 | *
25 | * @author:恒宇少年 - 于起宇
26 | */
27 | @Getter
28 | public enum ReportAway {
29 | /**
30 | * just report to admin
31 | */
32 | just,
33 | /**
34 | * timing report to admin with "reportIntervalSecond" config properties
35 | */
36 | timing
37 | }
38 |
--------------------------------------------------------------------------------
/minbox-logging-admin-ui/src/main/frontend/components/index.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014-2018 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 |
18 | const components = [];
19 |
20 | /* global require */
21 | const context = require.context('.', false, /^(?:(?!.*\.spec\.(js|vue)$).)*\.(js|vue)$/);
22 | context.keys().forEach(function (key) {
23 | const name = /^(.\/)+(.*)\.(vue|js)$/.exec(key)[2];
24 | components.push({name, component: context(key).default})
25 | });
26 |
27 | export default {
28 | install(Vue) {
29 | components.forEach(component => Vue.component(component.name, component.component));
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/minbox-logging-admin/src/main/java/org/minbox/framework/logging/admin/storage/mongo/GlobalLogMongoEntity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022. [恒宇少年 - 于起宇]
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.minbox.framework.logging.admin.storage.mongo;
18 |
19 | import lombok.AccessLevel;
20 | import lombok.Data;
21 | import lombok.NoArgsConstructor;
22 | import org.minbox.framework.logging.core.GlobalLog;
23 |
24 | /**
25 | * The {@link GlobalLog} mongo entity
26 | *
27 | * @author 恒宇少年
28 | */
29 | @Data
30 | @NoArgsConstructor(access = AccessLevel.PACKAGE)
31 | class GlobalLogMongoEntity extends GlobalLog {
32 | private String _id;
33 | }
34 |
--------------------------------------------------------------------------------
/minbox-logging-admin/src/main/java/org/minbox/framework/logging/admin/storage/mongo/RequestLogMongoEntity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022. [恒宇少年 - 于起宇]
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.minbox.framework.logging.admin.storage.mongo;
18 |
19 | import lombok.AccessLevel;
20 | import lombok.Data;
21 | import lombok.NoArgsConstructor;
22 | import org.minbox.framework.logging.core.MinBoxLog;
23 |
24 | /**
25 | * The {@link MinBoxLog} mongo entity
26 | *
27 | * @author 恒宇少年
28 | */
29 | @Data
30 | @NoArgsConstructor(access = AccessLevel.PACKAGE)
31 | class RequestLogMongoEntity extends MinBoxLog {
32 | private String _id;
33 | }
34 |
--------------------------------------------------------------------------------
/minbox-logging-admin-ui/src/main/frontend/utils/uri.spec.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014-2018 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import uri from './uri';
18 |
19 | describe('uri', () => {
20 |
21 | it('should escape uris properly', () => {
22 | expect(uri`http://app/${'foo/bar'}?q=${'???'}`).toBe('http://app/foo%2Fbar?q=%3F%3F%3F');
23 | expect(uri`http://app/${'foo/bar'}?q=1`).toBe('http://app/foo%2Fbar?q=1');
24 | expect(uri`http://app/${'foo/bar'}`).toBe('http://app/foo%2Fbar');
25 | expect(uri`http://app/foo`).toBe('http://app/foo');
26 | expect(uri``).toBe('');
27 | });
28 |
29 |
30 | });
31 |
--------------------------------------------------------------------------------
/minbox-logging-client/src/main/java/org/minbox/framework/logging/client/LoggingConstant.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright [2019] [恒宇少年 - 于起宇]
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | */
17 |
18 | package org.minbox.framework.logging.client;
19 |
20 | /**
21 | * Log Constant
22 | *
23 | * @author 恒宇少年
24 | */
25 | public interface LoggingConstant {
26 | /**
27 | * TraceId Header Name
28 | */
29 | String HEADER_NAME_TRACE_ID = "MINBOX-LOGGING-X-TRACE-ID";
30 | /**
31 | * Parent SpanId Header Name
32 | */
33 | String HEADER_NAME_PARENT_SPAN_ID = "MINBOX-LOGGING-X-PARENT-SPAN-ID";
34 | }
35 |
--------------------------------------------------------------------------------
/minbox-logging-admin-ui/src/main/frontend/utils/collections.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014-2019 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | export const compareBy = mapper => (a, b) => {
18 | const valA = mapper(a);
19 | const valB = mapper(b);
20 | return valA > valB ? 1 : valA < valB ? -1 : 0;
21 | };
22 |
23 | export const anyValueMatches = (obj, predicate) => {
24 | if (Array.isArray(obj)) {
25 | return obj.some(e => anyValueMatches(e, predicate));
26 | } else if (obj !== null && typeof obj === 'object') {
27 | return anyValueMatches(Object.values(obj), predicate);
28 | }
29 | return predicate(obj);
30 | };
31 |
--------------------------------------------------------------------------------
/minbox-logging-admin/src/main/java/org/minbox/framework/logging/admin/storage/mongo/MongoCollectionFields.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022. [恒宇少年 - 于起宇]
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.minbox.framework.logging.admin.storage.mongo;
18 |
19 | /**
20 | * The mongo collection fields
21 | *
22 | * @author 恒宇少年
23 | */
24 | public interface MongoCollectionFields {
25 | String SERVICE_DETAIL_ID = "_id";
26 | String SERVICE_ID = "serviceId";
27 | String SERVICE_IP = "serviceIp";
28 | String SERVICE_PORT = "servicePort";
29 | String SERVICE_LAST_REPORT_TIME = "lastReportTime";
30 |
31 | String LOG_CREATE_TIME = "createTime";
32 | }
33 |
--------------------------------------------------------------------------------
/minbox-logging-client/src/main/java/org/minbox/framework/logging/client/admin/discovery/lb/LoadBalanceNode.java:
--------------------------------------------------------------------------------
1 | package org.minbox.framework.logging.client.admin.discovery.lb;
2 |
3 | /**
4 | * Load Balance Node
5 | *
6 | * @author 恒宇少年
7 | */
8 | public class LoadBalanceNode {
9 | /**
10 | * node init weight
11 | */
12 | private int initWeight = 1;
13 | /**
14 | * logging admin address
15 | */
16 | private String address;
17 | /**
18 | * current weight
19 | */
20 | private int currentWeight;
21 |
22 | public LoadBalanceNode(String address) {
23 | this.address = address;
24 | }
25 |
26 | public int getInitWeight() {
27 | return initWeight;
28 | }
29 |
30 | public void setInitWeight(int initWeight) {
31 | this.initWeight = initWeight;
32 | }
33 |
34 | public String getAddress() {
35 | return address;
36 | }
37 |
38 | public void setAddress(String address) {
39 | this.address = address;
40 | }
41 |
42 | public int getCurrentWeight() {
43 | return currentWeight;
44 | }
45 |
46 | public void setCurrentWeight(int currentWeight) {
47 | this.currentWeight = currentWeight;
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/minbox-logging-core/src/main/java/org/minbox/framework/logging/core/annotation/Endpoint.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright [2019] [恒宇少年 - 于起宇]
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | */
17 |
18 | package org.minbox.framework.logging.core.annotation;
19 |
20 | import org.springframework.stereotype.Component;
21 |
22 | import java.lang.annotation.*;
23 |
24 | /**
25 | * ApiBoot Logging Endpoint Annotation
26 | * Only classes with this annotation will be scanned
27 | *
28 | * @author 恒宇少年
29 | */
30 | @Target({ElementType.TYPE})
31 | @Retention(RetentionPolicy.RUNTIME)
32 | @Documented
33 | @Component
34 | public @interface Endpoint {
35 | }
36 |
--------------------------------------------------------------------------------
/minbox-logging-admin-ui/src/main/frontend/utils/shortenClassname.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014-2018 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | export default (fullName, targetLength) => {
18 | if (!fullName || fullName.length < targetLength) {
19 | return fullName;
20 | }
21 |
22 | const tokens = fullName.split('.');
23 | let shortened = tokens.pop();
24 | while (tokens.length > 0) {
25 | const next = tokens.pop();
26 | if (next.length + 1 + shortened.length < targetLength) {
27 | shortened = next + '.' + shortened;
28 | } else {
29 | shortened = next[0] + '.' + shortened;
30 | }
31 | }
32 | return shortened;
33 | };
34 |
--------------------------------------------------------------------------------
/.github/workflows/deploy.yml:
--------------------------------------------------------------------------------
1 | # This is a basic workflow to help you get started with Actions
2 |
3 | name: Ci Builder
4 |
5 | # Controls when the action will run. Triggers the workflow on push or pull request
6 | # events but only for the master branch
7 | on:
8 | push:
9 | branches: [ master,develop ]
10 | pull_request:
11 | branches: [ master,develop ]
12 |
13 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel
14 | jobs:
15 | # This workflow contains a single job called "build"
16 | build:
17 | # The type of runner that the job will run on
18 | runs-on: ubuntu-latest
19 |
20 | # Steps represent a sequence of tasks that will be executed as part of the job
21 | steps:
22 | # Checkout source code
23 | - uses: actions/checkout@v2
24 | # Install Java 1.8
25 | - uses: actions/setup-java@v1
26 | with:
27 | java-version: 1.8
28 | # Cache maven .m2 directory
29 | - uses: actions/cache@v2
30 | with:
31 | path: ~/.m2/repository
32 | key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
33 | restore-keys: |
34 | ${{ runner.os }}-maven-
35 | # Publish to Apache Maven Central
36 | - run: mvn clean compile
--------------------------------------------------------------------------------
/minbox-logging-admin-ui/src/main/frontend/index.html:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | ApiBoot Logging Admin
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/minbox-logging-admin-ui/src/main/frontend/directives/sticks-below.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014-2018 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | const bind = (el, binding) => {
18 | if (!binding.value) {
19 | return;
20 | }
21 | const top = binding.value.map(v => document.querySelector(v))
22 | .filter(v => Boolean(v))
23 | .map(v => v.getBoundingClientRect().height)
24 | .reduce((a, b) => a + b, 0);
25 | el.style.top = `${top}px`;
26 | el.style.position = 'sticky';
27 | };
28 |
29 | export default {
30 | bind,
31 | update(el, binding) {
32 | if (binding.value === binding.oldValue) {
33 | return
34 | }
35 | bind(el, binding)
36 | }
37 | }
38 |
39 |
--------------------------------------------------------------------------------
/minbox-logging-admin-ui/src/main/frontend/views/index.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014-2018 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | const views = [];
18 |
19 | /* global require */
20 | const context = require.context('.', true, /^\.\/.+\/index\.(js|vue)$/);
21 | context.keys().forEach(function (key) {
22 | const defaultExport = context(key).default;
23 | if (defaultExport && defaultExport.install) {
24 | views.push(defaultExport)
25 | }
26 | });
27 |
28 | export const VIEW_GROUP = {
29 | WEB: 'web',
30 | INSIGHTS: 'insights',
31 | DATA: 'data',
32 | JVM: 'jvm',
33 | LOGGING: 'logging',
34 | NONE: 'none',
35 | SECURITY: 'security'
36 | };
37 |
38 | export default views;
39 |
--------------------------------------------------------------------------------
/minbox-logging-client/src/main/java/org/minbox/framework/logging/client/notice/LoggingNotice.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright [2019] [恒宇少年 - 于起宇]
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | */
17 |
18 | package org.minbox.framework.logging.client.notice;
19 |
20 | import org.minbox.framework.logging.core.MinBoxLog;
21 | import org.springframework.core.Ordered;
22 |
23 | /**
24 | * ApiBoot Logging Local Notice
25 | *
26 | * @author 恒宇少年
27 | */
28 | public interface LoggingNotice extends Ordered {
29 | /**
30 | * Local Notice ApiBoot Log Instance
31 | *
32 | * @param minBoxLog Log object for each HTTP request
33 | */
34 | void notice(MinBoxLog minBoxLog);
35 | }
36 |
--------------------------------------------------------------------------------
/minbox-logging-client/src/main/java/org/minbox/framework/logging/client/span/LogSpanIdGenerator.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright [2019] [恒宇少年 - 于起宇]
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | */
17 |
18 | package org.minbox.framework.logging.client.span;
19 |
20 |
21 | import org.minbox.framework.logging.client.MinBoxLoggingException;
22 |
23 | /**
24 | * ApiBoot Logging Span
25 | * Create new spanId
26 | *
27 | * @author 恒宇少年
28 | */
29 | public interface LogSpanIdGenerator {
30 | /**
31 | * create new spanId
32 | *
33 | * @return span id
34 | * @throws MinBoxLoggingException exception
35 | */
36 | String createSpanId() throws MinBoxLoggingException;
37 | }
38 |
--------------------------------------------------------------------------------
/minbox-logging-samples/logging-client-sample/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | minbox-logging-samples
7 | org.minbox.framework
8 | ${revision}
9 |
10 | 4.0.0
11 | jar
12 |
13 | "minbox-logging" 客户端集成使用示例
14 |
15 | logging-client-sample
16 |
17 |
18 | org.springframework.boot
19 | spring-boot-starter-web
20 |
21 |
22 | org.minbox.framework
23 | minbox-logging-client
24 |
25 |
26 | org.minbox.framework
27 | minbox-logging-spring-context
28 |
29 |
30 |
--------------------------------------------------------------------------------
/minbox-logging-admin-ui/src/main/frontend/mixins/subscribing.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014-2018 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | export default {
18 | created() {
19 | this.subscribe();
20 | },
21 | beforeDestroy() {
22 | this.unsubscribe();
23 | },
24 | methods: {
25 | async subscribe() {
26 | if (!this.subscription) {
27 | this.subscription = await this.createSubscription();
28 | }
29 | },
30 | unsubscribe() {
31 | if (this.subscription) {
32 | try {
33 | !this.subscription.closed && this.subscription.unsubscribe();
34 | } finally {
35 | this.subscription = null;
36 | }
37 | }
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/minbox-logging-client/src/main/java/org/minbox/framework/logging/client/admin/report/retry/LoggingReportRetrySupport.java:
--------------------------------------------------------------------------------
1 | package org.minbox.framework.logging.client.admin.report.retry;
2 |
3 | import org.minbox.framework.logging.core.MinBoxLog;
4 | import org.springframework.beans.factory.DisposableBean;
5 |
6 | import java.util.LinkedList;
7 | import java.util.List;
8 |
9 | /**
10 | * {@link LoggingReportRetry} Support
11 | *
12 | * @author 恒宇少年
13 | */
14 | public class LoggingReportRetrySupport implements LoggingReportRetry, DisposableBean {
15 | /**
16 | * the bean name of {@link LoggingReportRetrySupport}
17 | */
18 | public static final String BEAN_NAME = "loggingReportRetry";
19 | /**
20 | * Log waiting for retry report
21 | */
22 | private static final LinkedList LOGS = new LinkedList<>();
23 |
24 | @Override
25 | public void addToRetryCollection(MinBoxLog minBoxLog) {
26 | LOGS.add(minBoxLog);
27 | }
28 |
29 | @Override
30 | public void addToRetryCollection(List minBoxLogs) {
31 | LOGS.addAll(minBoxLogs);
32 | }
33 |
34 | @Override
35 | public List getAllRetryLogs() {
36 | return LOGS;
37 | }
38 |
39 | @Override
40 | public void destroy() throws Exception {
41 |
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/minbox-logging-admin-ui/src/main/frontend/views/wallboard/hex-mesh.spec.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014-2018 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import * as hm from './hex-mesh';
18 |
19 | describe('calcLayout', () => {
20 |
21 | it('should calculate optimum layout for 12 in 1594x879', () => {
22 | const result = hm.calcLayout(12, 1594, 879);
23 |
24 | expect(result).toEqual({
25 | rows: 3,
26 | cols: 5,
27 | sideLength: 175.8
28 | });
29 | });
30 |
31 | it('should calculate optimum layout for 1 in 100x100', () => {
32 | const result = hm.calcLayout(1, 100, 100);
33 |
34 | expect(result).toEqual({
35 | rows: 1,
36 | cols: 1,
37 | sideLength: 50
38 | });
39 | });
40 |
41 | });
42 |
--------------------------------------------------------------------------------
/minbox-logging-admin/src/main/java/org/minbox/framework/logging/admin/storage/mongo/ServiceEntity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022. [恒宇少年 - 于起宇]
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.minbox.framework.logging.admin.storage.mongo;
18 |
19 | import lombok.AccessLevel;
20 | import lombok.Data;
21 | import lombok.NoArgsConstructor;
22 |
23 | import java.time.LocalDateTime;
24 |
25 | /**
26 | * The service mongo entity
27 | *
28 | * @author 恒宇少年
29 | */
30 | @Data
31 | @NoArgsConstructor(access = AccessLevel.PACKAGE)
32 | class ServiceEntity {
33 | private String _id;
34 | private String serviceId;
35 | private String serviceIp;
36 | private int servicePort;
37 | private LocalDateTime lastReportTime;
38 | private LocalDateTime createTime = LocalDateTime.now();
39 | }
40 |
--------------------------------------------------------------------------------
/minbox-logging-admin/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | minbox-logging-dependencies
7 | org.minbox.framework
8 | ${revision}
9 | ../minbox-logging-dependencies
10 |
11 | 4.0.0
12 | jar
13 | minbox-logging-admin
14 |
15 |
16 | org.minbox.framework
17 | minbox-logging-core
18 | ${project.version}
19 |
20 |
21 | org.springframework
22 | spring-webmvc
23 | true
24 |
25 |
26 | org.springframework.data
27 | spring-data-mongodb
28 | true
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/minbox-logging-admin/src/main/java/org/minbox/framework/logging/admin/storage/mongo/MongoCollectionNames.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022. [恒宇少年 - 于起宇]
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.minbox.framework.logging.admin.storage.mongo;
18 |
19 | /**
20 | * The mongo collection names with minbox logging
21 | *
22 | * @author 恒宇少年
23 | */
24 | public interface MongoCollectionNames {
25 | /**
26 | * The {@link GlobalLogMongoEntity} storage collection name
27 | */
28 | String GLOBAL_LOG = "minbox-global-logs";
29 | /**
30 | * The {@link RequestLogMongoEntity} storage collection name
31 | */
32 | String REQUEST_LOG = "minbox-request-logs";
33 | /**
34 | * The {@link ServiceEntity} storage collection name
35 | */
36 | String SERVICE = "minbox-services";
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/minbox-logging-admin-ui/src/main/frontend/sba-config.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014-2019 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import merge from 'lodash/merge';
18 |
19 | const DEFAULT_CONFIG = {
20 | uiSettings: {
21 | brand: '',
22 | rememberMeEnabled: true,
23 | externalViews: [],
24 | favicon: 'assets/img/favicon.ico',
25 | faviconDanger: 'assets/img/favicon-danger.png',
26 | notificationFilterEnabled: false,
27 | routes: [],
28 | },
29 | user: null,
30 | extensions: [],
31 | externalViews: [],
32 | csrf: {
33 | parameterName: '_csrf',
34 | headerName: 'X-XSRF-TOKEN'
35 | },
36 | use: function (ext) {
37 | this.extensions.push(ext);
38 | }
39 | };
40 |
41 | export default merge(DEFAULT_CONFIG, global.SBA)
42 |
--------------------------------------------------------------------------------
/minbox-logging-client/src/main/java/org/minbox/framework/logging/client/tracer/LogTraceIdGenerator.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright [2019] [恒宇少年 - 于起宇]
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | */
17 |
18 | package org.minbox.framework.logging.client.tracer;
19 |
20 | import org.minbox.framework.logging.client.MinBoxLoggingException;
21 | import org.minbox.framework.logging.core.MinBoxLog;
22 |
23 | /**
24 | * ApiBoot Logging Tracer
25 | * Create new traceId
26 | *
27 | * @author 恒宇少年
28 | */
29 | public interface LogTraceIdGenerator {
30 | /**
31 | * Create new traceId
32 | *
33 | * @return The Trace ID of http request {@link MinBoxLog#getTraceId()}
34 | * @throws MinBoxLoggingException exception
35 | */
36 | String createTraceId() throws MinBoxLoggingException;
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/minbox-logging-admin-ui/src/main/frontend/directives/on-resize.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014-2018 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import ResizeObserver from 'resize-observer-polyfill';
18 |
19 | const observers = new WeakMap();
20 |
21 | const bind = (el, binding) => {
22 | unbind(el);
23 | const observer = new ResizeObserver(binding.value);
24 | observer.observe(el);
25 | observers.set(el, observer);
26 |
27 | };
28 |
29 | const unbind = (el) => {
30 | const observer = observers.get(el);
31 | if (observer) {
32 | observer.disconnect();
33 | observers.delete(el);
34 | }
35 | };
36 |
37 | export default {
38 | bind,
39 | update(el, binding) {
40 | if (binding.value === binding.oldValue) {
41 | return
42 | }
43 | bind(el, binding)
44 | },
45 | unbind
46 | }
47 |
48 |
--------------------------------------------------------------------------------
/minbox-logging-admin-ui/src/main/frontend/components/sba-tags.vue:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
43 |
--------------------------------------------------------------------------------
/minbox-logging-admin-ui/src/main/frontend/components/sba-time-ago.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014-2018 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import moment from 'moment-shortformat';
18 |
19 | export default {
20 | props: {
21 | date: {
22 | type: [String, Date, Number, moment],
23 | default: null
24 | }
25 | },
26 | data: () => ({
27 | now: moment(),
28 | timer: null,
29 | }),
30 | computed: {
31 | timeAgo() {
32 | return moment(this.date).short(true, this.now);
33 | }
34 | },
35 | created() {
36 | this.timer = window.setInterval(() => {
37 | this.now = moment();
38 | }, 1000);
39 | },
40 | render() {
41 | return this._v(this.timeAgo);
42 | },
43 | beforeDestroy() {
44 | if (this.timer) {
45 | window.clearInterval(this.timer);
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/minbox-logging-admin-ui/src/main/frontend/directives/popper.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014-2018 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import Popper from 'popper.js';
18 |
19 | const poppers = new WeakMap();
20 |
21 | const bind = (el, binding) => {
22 | const reference = typeof binding.value === 'string' ? document.getElementById(binding.value) : binding.value;
23 | if (reference) {
24 | const popper = new Popper(reference, el);
25 | poppers.set(el, popper);
26 | }
27 | };
28 |
29 | const unbind = (el) => {
30 | const popper = poppers.get(el);
31 | if (popper) {
32 | popper.destroy(el);
33 | }
34 | };
35 |
36 | export default {
37 | bind,
38 | update(el, binding) {
39 | if (binding.value === binding.oldValue) {
40 | return
41 | }
42 | bind(el, binding)
43 | },
44 | unbind
45 | }
46 |
47 |
48 |
--------------------------------------------------------------------------------
/minbox-logging-spring-context/src/main/java/org/minbox/framework/logging/spring/context/annotation/client/LoggingClientBeanDefinitionRegistrar.java:
--------------------------------------------------------------------------------
1 | package org.minbox.framework.logging.spring.context.annotation.client;
2 |
3 | import org.minbox.framework.logging.client.interceptor.web.LoggingWebInterceptor;
4 | import org.minbox.framework.logging.spring.util.LoggingBeanUtils;
5 | import org.slf4j.Logger;
6 | import org.slf4j.LoggerFactory;
7 | import org.springframework.beans.factory.support.BeanDefinitionRegistry;
8 | import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
9 | import org.springframework.core.type.AnnotationMetadata;
10 |
11 | /**
12 | * Register logging client beans {@link org.minbox.framework.logging.spring.util.LoggingBeanUtils#registerLoggingClientBeans(BeanDefinitionRegistry)}
13 | * register {@link LoggingWebInterceptor}
14 | *
15 | * @author 恒宇少年
16 | */
17 | public class LoggingClientBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
18 | /**
19 | * logger instance
20 | */
21 | static Logger logger = LoggerFactory.getLogger(LoggingClientBeanDefinitionRegistrar.class);
22 |
23 | @Override
24 | public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
25 | LoggingBeanUtils.registerLoggingClientBeans(registry);
26 | logger.info("Logging client beans register successfully.");
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/minbox-logging-admin-ui/src/main/frontend/store.spec.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014-2019 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import Application from '@/services/application';
18 | import {EMPTY} from '@/utils/rxjs';
19 | import Store from './store';
20 |
21 | jest.mock('@/services/application');
22 | jest.setTimeout(500);
23 |
24 | describe('store', () => {
25 | describe('given no registered applications', function () {
26 | Application.list = jest.fn(() => EMPTY);
27 |
28 | it('it should emit a connected event after start', async () => {
29 | const store = new Store();
30 |
31 | const connectedEvent = new Promise(resolve => {
32 | store.addEventListener('connected', resolve)
33 | });
34 |
35 | store.start();
36 | await connectedEvent;
37 | store.stop();
38 | });
39 |
40 | });
41 | });
42 |
--------------------------------------------------------------------------------
/minbox-logging-admin-ui/src/main/frontend/utils/autolink.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014-2018 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import _Autolinker from 'autolinker';
18 |
19 | export const defaults = {
20 | urls: {
21 | schemeMatches: true,
22 | wwwMatches: false,
23 | tldMatches: false
24 | },
25 | email: false,
26 | phone: false,
27 | mention: false,
28 | hashtag: false,
29 |
30 | stripPrefix: false,
31 | stripTrailingSlash: false,
32 | newWindow: true,
33 |
34 | truncate: {
35 | length: 0,
36 | location: 'smart'
37 | },
38 |
39 | className: ''
40 | };
41 | const autolinker = new _Autolinker(defaults);
42 |
43 | export default s => autolinker.link(s);
44 | export function Autolink(cfg) {
45 | this.autolinker = new _Autolinker({...defaults, ...cfg});
46 | return s => this.autolinker.link(s)
47 | }
48 |
--------------------------------------------------------------------------------
/minbox-logging-client/src/main/java/org/minbox/framework/logging/client/notice/LoggingNoticeEvent.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright [2019] [恒宇少年 - 于起宇]
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | */
17 |
18 | package org.minbox.framework.logging.client.notice;
19 |
20 | import lombok.Getter;
21 | import org.minbox.framework.logging.core.MinBoxLog;
22 | import org.springframework.context.ApplicationEvent;
23 |
24 | /**
25 | * ApiBoot Logging Notice Event
26 | * Log objects can be obtained by listening for this event
27 | *
28 | * @author 恒宇少年
29 | */
30 | @Getter
31 | public class LoggingNoticeEvent extends ApplicationEvent {
32 | /**
33 | * ApiBoot Logging Object
34 | */
35 | private MinBoxLog log;
36 |
37 | public LoggingNoticeEvent(Object source, MinBoxLog log) {
38 | super(source);
39 | this.log = log;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/minbox-logging-admin-ui/src/main/frontend/components/sba-formatted-obj.vue:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
19 |
20 |
21 |
44 |
45 |
50 |
--------------------------------------------------------------------------------
/minbox-logging-admin-ui/src/main/frontend/utils/axios.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014-2019 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | import sbaConfig from '@/sba-config'
17 | import axios from 'axios';
18 |
19 | axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
20 | axios.defaults.xsrfHeaderName = sbaConfig.csrf.headerName;
21 |
22 | export const redirectOn401 = (predicate = () => true) => error => {
23 | if (error.response && error.response.status === 401 && predicate(error)) {
24 | window.location.assign(`login?redirectTo=${encodeURIComponent(window.location.href)}`);
25 | }
26 | return Promise.reject(error);
27 |
28 | };
29 |
30 | const instance = axios.create({headers: {'Accept': 'application/json'}});
31 | instance.interceptors.response.use(response => response, redirectOn401());
32 | instance.create = axios.create;
33 |
34 | export default instance;
35 |
--------------------------------------------------------------------------------
/minbox-logging-samples/logging-admin-sample/src/main/java/org/minbox/framework/logging/admin/sample/LoggingAdminConfiguration.java:
--------------------------------------------------------------------------------
1 | package org.minbox.framework.logging.admin.sample;
2 |
3 | import org.minbox.framework.logging.admin.LoggingAdminFactoryBean;
4 | import org.minbox.framework.logging.admin.storage.LoggingDataSourceStorage;
5 | import org.springframework.context.annotation.Bean;
6 | import org.springframework.context.annotation.Configuration;
7 |
8 | import javax.sql.DataSource;
9 |
10 | /**
11 | * @author:恒宇少年 - 于起宇
12 | *
13 | * DateTime:2019/9/14 8:31 下午
14 | * Blog:http://blog.yuqiyu.com
15 | * WebSite:http://www.jianshu.com/u/092df3f77bca
16 | * Gitee:https://gitee.com/hengboy
17 | * GitHub:https://github.com/hengboy
18 | */
19 | @Configuration
20 | public class LoggingAdminConfiguration {
21 |
22 | /**
23 | * 当bean容器内存在{@link DataSource}对象实例时创建{@link LoggingAdminFactoryBean}示例
24 | *
25 | * @param dataSource {@link DataSource}
26 | * @return {@link LoggingAdminFactoryBean}
27 | */
28 | @Bean
29 | public LoggingAdminFactoryBean dataSourceLoggingAdminFactoryBean(DataSource dataSource) {
30 | LoggingAdminFactoryBean adminFactoryBean = new LoggingAdminFactoryBean();
31 | adminFactoryBean.setShowConsoleReportLog(true);
32 | adminFactoryBean.setFormatConsoleLogJson(true);
33 | adminFactoryBean.setLoggingStorage(new LoggingDataSourceStorage(dataSource));
34 | return adminFactoryBean;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/minbox-logging-client/src/main/java/org/minbox/framework/logging/client/admin/discovery/lb/support/DefaultLoadBalanceStrategy.java:
--------------------------------------------------------------------------------
1 | package org.minbox.framework.logging.client.admin.discovery.lb.support;
2 |
3 | import org.minbox.framework.logging.client.MinBoxLoggingException;
4 | import org.minbox.framework.logging.client.admin.discovery.lb.LoadBalanceNode;
5 | import org.minbox.framework.logging.client.admin.discovery.lb.LoadBalanceStrategy;
6 | import org.springframework.util.ObjectUtils;
7 |
8 | import java.util.Arrays;
9 | import java.util.LinkedList;
10 | import java.util.List;
11 |
12 | /**
13 | * The {@link LoadBalanceStrategy} default support
14 | *
15 | * @author 恒宇少年
16 | * @see LoadBalanceNode
17 | */
18 | public abstract class DefaultLoadBalanceStrategy implements LoadBalanceStrategy {
19 |
20 | /**
21 | * Initialize the list of transformation nodes
22 | * Convert admin address to {@link LoadBalanceNode}
23 | *
24 | * @param adminAddress logging admin address array
25 | * @return {@link LoadBalanceNode} collection
26 | */
27 | protected List initNodeList(String[] adminAddress) {
28 | if (ObjectUtils.isEmpty(adminAddress)) {
29 | throw new MinBoxLoggingException("Admin address not configured.");
30 | }
31 | List nodes = new LinkedList();
32 | Arrays.stream(adminAddress).forEach(address -> nodes.add(new LoadBalanceNode(address)));
33 | return nodes;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/minbox-logging-admin-ui/src/main/frontend/utils/shortenClassname.spec.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014-2018 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import shortenClassname from './shortenClassname';
18 |
19 | describe('shortenClassname', () => {
20 |
21 | it('should shorten when too long', () => {
22 | expect(shortenClassname('de.codecentric.boot.admin.server.config.AdminServerAutoConfiguration', 40)).toBe('d.c.b.a.s.config.AdminServerAutoConfiguration')
23 | });
24 |
25 | it('should not shorten when string is small enough', () => {
26 | expect(shortenClassname('de.codecentric.boot.admin.server.config.AdminServerAutoConfiguration', 300)).toBe('de.codecentric.boot.admin.server.config.AdminServerAutoConfiguration')
27 | });
28 |
29 | it('should not shorten when no package is present', () => {
30 | expect(shortenClassname('AdminServerAutoConfiguration', 1)).toBe('AdminServerAutoConfiguration')
31 | });
32 | });
33 |
--------------------------------------------------------------------------------
/minbox-logging-client/src/main/java/org/minbox/framework/logging/client/admin/discovery/support/LoggingAbstractAdminDiscovery.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright [2019] [恒宇少年 - 于起宇]
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | */
17 |
18 | package org.minbox.framework.logging.client.admin.discovery.support;
19 |
20 | import org.minbox.framework.logging.client.admin.discovery.LoggingAdminDiscovery;
21 |
22 | import java.util.Base64;
23 |
24 | /**
25 | * ApiBoot Logging Abstract Admin Discovery
26 | *
27 | * @author 恒宇少年
28 | */
29 | public abstract class LoggingAbstractAdminDiscovery implements LoggingAdminDiscovery {
30 | /**
31 | * get basic auth base64 string
32 | *
33 | * @param basicInfo basic info
34 | * @return basic auth base64 string
35 | */
36 | protected String getBasicBase64(String basicInfo) {
37 | return Base64.getEncoder().encodeToString(basicInfo.getBytes());
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/minbox-logging-admin-ui/src/main/frontend/utils/objToString.spec.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014-2018 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import objToString from './objToString'
18 |
19 | describe('objToString should', () => {
20 |
21 | it('return the input string for normal text', () => {
22 | const obj = {
23 | a: 'start',
24 | b: 1,
25 | c: true,
26 | d: [1, 2, [3, 4]],
27 | e: {
28 | f: '',
29 | g: 1,
30 | h: null,
31 | i: undefined,
32 | j: {},
33 | k: [1],
34 | l: [{a:1, b:'foo'}, {b:2}]
35 | }
36 | };
37 | const str = `a: start
38 | b: 1
39 | c: true
40 | d:
41 | - 1
42 | - 2
43 | -
44 | - 3
45 | - 4
46 | e:
47 | f:
48 | g: 1
49 | h: null
50 | i:
51 | j: {}
52 | k:
53 | - 1
54 | l:
55 | -
56 | a: 1
57 | b: foo
58 | -
59 | b: 2`;
60 | expect(objToString(obj)).toBe(str);
61 | });
62 |
63 | });
64 |
--------------------------------------------------------------------------------
/minbox-logging-admin/src/main/java/org/minbox/framework/logging/admin/event/ReportLogEvent.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright [2019] [恒宇少年 - 于起宇]
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | */
17 |
18 | package org.minbox.framework.logging.admin.event;
19 |
20 | import lombok.Getter;
21 | import org.minbox.framework.logging.core.LoggingClientNotice;
22 | import org.springframework.context.ApplicationEvent;
23 |
24 | /**
25 | * The time of publication after receiving the reported log information
26 | *
27 | * @author 恒宇少年
28 | * @see org.minbox.framework.logging.admin.endpoint.LoggingEndpoint
29 | */
30 | @Getter
31 | public class ReportLogEvent extends ApplicationEvent {
32 | /**
33 | * ApiBoot Log Client Report Notice Object
34 | */
35 | private LoggingClientNotice logClientNotice;
36 |
37 | public ReportLogEvent(Object source, LoggingClientNotice logClientNotice) {
38 | super(source);
39 | this.logClientNotice = logClientNotice;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/minbox-logging-client/src/main/java/org/minbox/framework/logging/client/global/GlobalLoggingThreadLocal.java:
--------------------------------------------------------------------------------
1 | package org.minbox.framework.logging.client.global;
2 |
3 | import com.alibaba.ttl.TransmittableThreadLocal;
4 | import org.minbox.framework.logging.core.GlobalLog;
5 | import org.springframework.util.ObjectUtils;
6 |
7 | import java.util.LinkedList;
8 | import java.util.List;
9 |
10 | /**
11 | * Use threadLocal to store all GlobalLogs in a request that need to be saved
12 | *
13 | * @author 恒宇少年
14 | */
15 | public class GlobalLoggingThreadLocal {
16 | /**
17 | * GlobalLog {@link ThreadLocal} define
18 | */
19 | private static final TransmittableThreadLocal> GLOBAL_LOGS = new TransmittableThreadLocal();
20 |
21 | /**
22 | * Get {@link GlobalLog} List from ThreadLocal
23 | *
24 | * @return {@link GlobalLog}
25 | */
26 | public static List getGlobalLogs() {
27 | return GLOBAL_LOGS.get();
28 | }
29 |
30 | /**
31 | * Add {@link GlobalLog} to ThreadLocal
32 | *
33 | * @param globalLog {@link GlobalLog}
34 | */
35 | public static void addGlobalLogs(GlobalLog globalLog) {
36 | List globalLogs = getGlobalLogs();
37 | if (ObjectUtils.isEmpty(globalLogs)) {
38 | globalLogs = new LinkedList();
39 | }
40 | globalLogs.add(globalLog);
41 | GLOBAL_LOGS.set(globalLogs);
42 | }
43 |
44 | /**
45 | * Delete {@link GlobalLog} list in ThreadLocal
46 | */
47 | public static void remove() {
48 | GLOBAL_LOGS.remove();
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/minbox-logging-client/src/main/java/org/minbox/framework/logging/client/tracer/support/DefaultLogTraceIdGenerator.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright [2019] [恒宇少年 - 于起宇]
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | */
17 |
18 | package org.minbox.framework.logging.client.tracer.support;
19 |
20 | import org.minbox.framework.logging.client.MinBoxLoggingException;
21 | import org.minbox.framework.logging.client.tracer.LogTraceIdGenerator;
22 | import org.minbox.framework.logging.core.MinBoxLog;
23 |
24 | import java.util.UUID;
25 |
26 | /**
27 | * The default support of {@link LogTraceIdGenerator}
28 | *
29 | * @author 恒宇少年
30 | */
31 | public class DefaultLogTraceIdGenerator implements LogTraceIdGenerator {
32 | /**
33 | * Use UUID as the default traceId
34 | *
35 | * @return {@link MinBoxLog#getTraceId()}
36 | * @throws MinBoxLoggingException Exception
37 | */
38 | @Override
39 | public String createTraceId() throws MinBoxLoggingException {
40 | return UUID.randomUUID().toString();
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/minbox-logging-admin-ui/src/main/frontend/components/sba-time-ago.spec.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014-2018 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import {shallowMount} from '@vue/test-utils';
18 | import moment from 'moment';
19 | import sbaTimeAgo from './sba-time-ago.js';
20 |
21 | moment.now = () => +new Date(1318781879406);
22 |
23 | describe('time-ago', () => {
24 |
25 | describe('given a short time passed time', () => {
26 | it('should match the snapshot', () => {
27 | const wrapper = shallowMount(sbaTimeAgo, {
28 | propsData: {
29 | date: moment(1318781000000).utc()
30 | }
31 | });
32 | expect(wrapper.vm.$el).toMatchSnapshot();
33 | });
34 | });
35 |
36 | describe('given a long time passed time', () => {
37 | it('should match the snapshot', () => {
38 | const wrapper = shallowMount(sbaTimeAgo, {
39 | propsData: {
40 | date: moment(1310000000000).utc()
41 | }
42 | });
43 | expect(wrapper.vm.$el).toMatchSnapshot();
44 | });
45 | });
46 |
47 | });
48 |
--------------------------------------------------------------------------------
/minbox-logging-client/src/main/java/org/minbox/framework/logging/client/admin/report/LoggingAdminReport.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright [2019] [恒宇少年 - 于起宇]
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | */
17 |
18 | package org.minbox.framework.logging.client.admin.report;
19 |
20 | import org.minbox.framework.logging.client.MinBoxLoggingException;
21 | import org.minbox.framework.logging.core.MinBoxLog;
22 |
23 | import java.util.List;
24 |
25 | /**
26 | * Batch Report Request Logs To Admin
27 | *
28 | * @author 恒宇少年
29 | */
30 | public interface LoggingAdminReport {
31 | /**
32 | * Report Request Logs To Admin
33 | * Loading a specified number of logs from the cache
34 | *
35 | * @throws MinBoxLoggingException Logging Exception
36 | */
37 | void report() throws MinBoxLoggingException;
38 |
39 | /**
40 | * Report Specified Request Logs
41 | *
42 | * @param logs Request Logs
43 | * @throws MinBoxLoggingException Logging Exception
44 | */
45 | void report(List logs) throws MinBoxLoggingException;
46 | }
47 |
--------------------------------------------------------------------------------
/minbox-logging-client/src/main/java/org/minbox/framework/logging/client/span/support/DefaultLogSpanIdGenerator.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright [2019] [恒宇少年 - 于起宇]
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | */
17 |
18 | package org.minbox.framework.logging.client.span.support;
19 |
20 |
21 | import org.minbox.framework.logging.client.MinBoxLoggingException;
22 | import org.minbox.framework.logging.client.span.LogSpanIdGenerator;
23 | import org.minbox.framework.logging.core.MinBoxLog;
24 |
25 | import java.util.UUID;
26 |
27 | /**
28 | * ApiBoot Logging Default Span
29 | * Use By Create New SpanId
30 | *
31 | * @author 恒宇少年
32 | */
33 | public class DefaultLogSpanIdGenerator implements LogSpanIdGenerator {
34 | /**
35 | * Create New SpanId
36 | * Use random uuid as default spanId
37 | *
38 | * @return {@link MinBoxLog#getSpanId()}
39 | * @throws MinBoxLoggingException Exception
40 | */
41 | @Override
42 | public String createSpanId() throws MinBoxLoggingException {
43 | return UUID.randomUUID().toString();
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/minbox-logging-admin-ui/src/main/frontend/i18n/i18n.zh.json:
--------------------------------------------------------------------------------
1 | {
2 | "error": {
3 | "server_connection_failed": "Server connection failed. "
4 | },
5 | "log": {
6 | "title": "链路日志列表",
7 | "top-menu": "链路日志",
8 | "time": "请求时间",
9 | "traceId": "链路编号",
10 | "uri": "请求日志",
11 | "status": "响应状态",
12 | "method": "请求方式",
13 | "serviceId": "服务ID",
14 | "consumeTime": "耗时(ms)"
15 | },
16 | "services": {
17 | "top-menu": "日志服务",
18 | "title": "服务列表",
19 | "id": "服务ID",
20 | "ip": "服务IP",
21 | "port": "服务端口号",
22 | "lastReportTime": "最后上报时间",
23 | "createTime": "首次上报时间"
24 | },
25 | "term": {
26 | "application": "Application",
27 | "attributes": "Attributes",
28 | "bytes": "Bytes",
29 | "cancel": "Cancel",
30 | "clear": "Clear",
31 | "cleared": "Cleared",
32 | "close": "Close",
33 | "confirm": "Confirm",
34 | "delete": "Delete",
35 | "deleted": "Deleted",
36 | "duration": "Duration",
37 | "event": "Event",
38 | "ever": "ever",
39 | "executing": "Executing...",
40 | "execution_failed": "Execution failed.",
41 | "execution_successful": "Execution successful.",
42 | "failed": "Failed",
43 | "float": "Float",
44 | "hours": "{count} hour | {count} hours",
45 | "instances": "Instances",
46 | "integer": "Integer",
47 | "milliseconds": "Milliseconds",
48 | "minutes": "{count} minute | {count} minutes",
49 | "name": "Name",
50 | "operations": "Operations",
51 | "save": "Save",
52 | "stacktrace": "Stacktrace",
53 | "suppress": "Suppress",
54 | "time": "Time",
55 | "unsuppress": "Unsuppress",
56 | "username": "Username"
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/minbox-logging-client/src/main/java/org/minbox/framework/logging/client/admin/discovery/LoggingAdminDiscovery.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright [2019] [恒宇少年 - 于起宇]
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | */
17 |
18 | package org.minbox.framework.logging.client.admin.discovery;
19 |
20 | import org.minbox.framework.logging.client.MinBoxLoggingException;
21 |
22 | /**
23 | * Look Up ApiBoot Logging Admin Service Urls
24 | * 1. single api-boot-logging-admin service
25 | * 2. pull api-boot-logging-admin services from registry center
26 | *
27 | * @author 恒宇少年
28 | */
29 | public interface LoggingAdminDiscovery {
30 | /**
31 | * lookup a api-boot-logging-admin service url
32 | *
33 | * @return service url
34 | * @throws MinBoxLoggingException Logging Exception
35 | */
36 | String lookup() throws MinBoxLoggingException;
37 |
38 | /**
39 | * get basic auth info
40 | * if config spring security user
41 | *
42 | * @return spring security user info
43 | * @throws MinBoxLoggingException Logging Exception
44 | */
45 | String getBasicAuth() throws MinBoxLoggingException;
46 | }
47 |
--------------------------------------------------------------------------------
/minbox-logging-admin-ui/src/main/frontend/assets/css/_utilities.scss:
--------------------------------------------------------------------------------
1 | /*!
2 | * Copyright 2014-2018 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | // Import the initial variables
17 | @import "~bulma/sass/utilities/initial-variables";
18 | @import "~bulma/sass/utilities/functions";
19 |
20 | //$turquoise: rgb(66, 211, 165);
21 | $turquoise: #78a744;
22 | // overrides
23 | $primary: $turquoise;
24 | $primary-invert: $white;
25 |
26 | // Add new color variables to the color map.
27 | @import "~bulma/sass/utilities/derived-variables.sass";
28 |
29 | $addColors: ();
30 | $colors: map-merge($colors, $addColors);
31 |
32 | $link: $primary;
33 |
34 | $modal-card-head-background-color: $white;
35 | $modal-content-width: calc(100vh - 40px);
36 |
37 | $navbar-background-color: $black-ter;
38 | $navbar-item-color: $grey;
39 | $navbar-item-hover-color: $white;
40 | $navbar-item-hover-background-color: $navbar-background-color;
41 | $navbar-item-active-color: $white;
42 | $navbar-item-active-background-color: $navbar-background-color;
43 |
44 | @import "~bulma/sass/utilities/mixins.sass";
45 |
46 | // for calculations / originally rem
47 | $navbar-height-px: 52px;
48 |
--------------------------------------------------------------------------------
/minbox-logging-client/src/main/java/org/minbox/framework/logging/client/global/GlobalLogging.java:
--------------------------------------------------------------------------------
1 | package org.minbox.framework.logging.client.global;
2 |
3 | /**
4 | * Global log collection interface
5 | * Provide debug, info, and error log collection
6 | *
7 | * @author 恒宇少年
8 | */
9 | public interface GlobalLogging {
10 | /**
11 | * Collect Debug Level Logs
12 | *
13 | * @param msg log content
14 | */
15 | void debug(String msg);
16 |
17 | /**
18 | * Collect Debug Level Logs
19 | *
20 | * @param format Unformatted log content
21 | * @param arguments List of parameters corresponding to log content
22 | */
23 | void debug(String format, Object... arguments);
24 |
25 | /**
26 | * Collect Info Level Logs
27 | *
28 | * @param msg log content
29 | */
30 | void info(String msg);
31 |
32 | /**
33 | * Collect Info Level Logs
34 | *
35 | * @param format Unformatted log content
36 | * @param arguments List of parameters corresponding to log content
37 | */
38 | void info(String format, Object... arguments);
39 |
40 | /**
41 | * Collect Error Level Logs
42 | *
43 | * @param msg log content
44 | */
45 | void error(String msg);
46 |
47 | /**
48 | * Collect Error Level Logs
49 | *
50 | * @param msg log content
51 | * @param throwable Exception object instance
52 | */
53 | void error(String msg, Throwable throwable);
54 |
55 | /**
56 | * Collect Error Level Logs
57 | *
58 | * @param format Unformatted log content
59 | * @param arguments List of parameters corresponding to log content
60 | */
61 | void error(String format, Object... arguments);
62 | }
63 |
--------------------------------------------------------------------------------
/minbox-logging-spring-context/src/main/java/org/minbox/framework/logging/spring/context/annotation/admin/LoggingAdminBeanDefinitionRegistrar.java:
--------------------------------------------------------------------------------
1 | package org.minbox.framework.logging.spring.context.annotation.admin;
2 |
3 | import org.minbox.framework.logging.spring.util.LoggingBeanUtils;
4 | import org.slf4j.Logger;
5 | import org.slf4j.LoggerFactory;
6 | import org.springframework.beans.factory.support.BeanDefinitionRegistry;
7 | import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
8 | import org.springframework.core.type.AnnotationMetadata;
9 |
10 | /**
11 | * Register logging admin beans{@link LoggingBeanUtils#registerLoggingAdminBeans(BeanDefinitionRegistry)}
12 | * register {@link org.minbox.framework.logging.admin.storage.LoggingDataSourceStorage}
13 | * register {@link org.minbox.framework.logging.admin.listener.ReportLogStorageListener}
14 | * register {@link org.minbox.framework.logging.admin.listener.ReportLogJsonFormatListener}
15 | * register {@link org.minbox.framework.logging.admin.endpoint.LoggingEndpoint}
16 | *
17 | * @author 恒宇少年
18 | */
19 | public class LoggingAdminBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
20 | /**
21 | * logger instance
22 | */
23 | static Logger logger = LoggerFactory.getLogger(LoggingAdminBeanDefinitionRegistrar.class);
24 |
25 | @Override
26 | public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
27 | LoggingBeanUtils.registerLoggingAdminBeans(registry);
28 | logger.info("Logging admin beans register successfully.");
29 | LoggingBeanUtils.registerLoggingAdminUiBeans(registry);
30 | logger.info("Logging admin ui beans register successfully.");
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/minbox-logging-samples/logging-admin-sample/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | minbox-logging-samples
7 | org.minbox.framework
8 | ${revision}
9 |
10 | 4.0.0
11 | jar
12 | logging-admin-sample
13 |
14 |
15 | org.springframework.boot
16 | spring-boot-starter-web
17 |
18 |
19 | org.minbox.framework
20 | minbox-logging-admin
21 |
22 |
23 | org.minbox.framework
24 | minbox-logging-admin-ui
25 |
26 |
27 | org.minbox.framework
28 | minbox-logging-spring-context
29 |
30 |
31 | mysql
32 | mysql-connector-java
33 |
34 |
35 | com.zaxxer
36 | HikariCP
37 |
38 |
39 | org.minbox.framework
40 | api-boot-starter-mybatis-enhance
41 |
42 |
43 |
--------------------------------------------------------------------------------
/minbox-logging-client/src/main/java/org/minbox/framework/logging/client/notice/support/LoggingLocalNotice.java:
--------------------------------------------------------------------------------
1 | package org.minbox.framework.logging.client.notice.support;
2 |
3 | import org.minbox.framework.logging.client.LoggingFactoryBean;
4 | import org.minbox.framework.logging.client.notice.LoggingNotice;
5 | import org.minbox.framework.logging.core.MinBoxLog;
6 | import org.minbox.framework.util.JsonUtils;
7 | import org.slf4j.Logger;
8 | import org.slf4j.LoggerFactory;
9 |
10 | /**
11 | * Local console log notification
12 | *
13 | * @author 恒宇少年
14 | */
15 | public class LoggingLocalNotice implements LoggingNotice {
16 | /**
17 | * the bean name of {@link LoggingLocalNotice}
18 | */
19 | public static final String BEAN_NAME = "loggingLocalNotice";
20 | /**
21 | * logger instance
22 | */
23 | static Logger logger = LoggerFactory.getLogger(LoggingLocalNotice.class);
24 | /**
25 | * Logging factory bean {@link LoggingFactoryBean}
26 | */
27 | private LoggingFactoryBean loggingFactoryBean;
28 |
29 | public LoggingLocalNotice(LoggingFactoryBean loggingFactoryBean) {
30 | this.loggingFactoryBean = loggingFactoryBean;
31 | }
32 |
33 | /**
34 | * Output formatted log information according to configuration in console
35 | * {@link LoggingNotice}
36 | *
37 | * @param minBoxLog ApiBoot Log
38 | */
39 | @Override
40 | public void notice(MinBoxLog minBoxLog) {
41 | if (loggingFactoryBean.isShowConsoleLog()) {
42 | logger.debug("Request Uri:{}, Logging:\n{}", minBoxLog.getRequestUri(),
43 | loggingFactoryBean.isFormatConsoleLog() ? JsonUtils.beautifyJson(minBoxLog) : JsonUtils.toJsonString(minBoxLog));
44 | }
45 | }
46 |
47 | @Override
48 | public int getOrder() {
49 | return HIGHEST_PRECEDENCE;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/minbox-logging-admin-ui/src/main/frontend/components/sba-icon-button.vue:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
21 |
22 |
23 |
41 |
42 |
74 |
--------------------------------------------------------------------------------
/minbox-logging-core/src/main/java/org/minbox/framework/logging/core/GlobalLog.java:
--------------------------------------------------------------------------------
1 | package org.minbox.framework.logging.core;
2 |
3 | import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
4 | import com.fasterxml.jackson.databind.annotation.JsonSerialize;
5 | import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
6 | import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
7 | import lombok.Data;
8 |
9 | import java.io.Serializable;
10 | import java.time.LocalDateTime;
11 |
12 | /**
13 | * Global log data entity
14 | *
15 | * @author 恒宇少年
16 | */
17 | @Data
18 | public class GlobalLog implements Serializable {
19 | /**
20 | * The request log id
21 | */
22 | private String requestLogId;
23 | /**
24 | * Global log level
25 | * {@link GlobalLogLevel}
26 | */
27 | private GlobalLogLevel level;
28 | /**
29 | * all level's log content
30 | */
31 | private String content;
32 | /**
33 | * Error stack information collected in error level logs
34 | */
35 | private String exceptionStack;
36 | /**
37 | * caller class name
38 | * {@link StackTraceElement#getClassName()}
39 | */
40 | private String callerClass;
41 | /**
42 | * caller method name
43 | * {@link StackTraceElement#getMethodName()}
44 | */
45 | private String callerMethod;
46 | /**
47 | * caller code line number
48 | * {@link StackTraceElement#getLineNumber()}
49 | */
50 | private int callerCodeLineNumber;
51 | /**
52 | * the global log create time
53 | * default is current time millis
54 | */
55 | /**
56 | * The request logs create time
57 | */
58 | @JsonSerialize(using = LocalDateTimeSerializer.class)
59 | @JsonDeserialize(using = LocalDateTimeDeserializer.class)
60 | private LocalDateTime createTime = LocalDateTime.now();
61 | }
62 |
--------------------------------------------------------------------------------
/minbox-logging-client/src/main/java/org/minbox/framework/logging/client/interceptor/LoggingAbstractInterceptor.java:
--------------------------------------------------------------------------------
1 | package org.minbox.framework.logging.client.interceptor;
2 |
3 | import org.minbox.framework.logging.client.LoggingFactoryBean;
4 | import org.minbox.framework.logging.client.span.LogSpanIdGenerator;
5 | import org.minbox.framework.logging.client.span.support.DefaultLogSpanIdGenerator;
6 | import org.minbox.framework.logging.client.tracer.LogTraceIdGenerator;
7 | import org.minbox.framework.logging.client.tracer.support.DefaultLogTraceIdGenerator;
8 | import org.slf4j.Logger;
9 | import org.slf4j.LoggerFactory;
10 |
11 | /**
12 | * The {@link LoggingInterceptor} basic support
13 | *
14 | * @author 恒宇少年
15 | */
16 | public class LoggingAbstractInterceptor implements LoggingInterceptor {
17 | /**
18 | * logger instance
19 | */
20 | static Logger logger = LoggerFactory.getLogger(LoggingAbstractInterceptor.class);
21 | /**
22 | * logging factory bean
23 | * {@link LoggingFactoryBean}
24 | */
25 | private LoggingFactoryBean factoryBean;
26 |
27 | public LoggingAbstractInterceptor(LoggingFactoryBean factoryBean) {
28 | this.factoryBean = factoryBean;
29 | }
30 |
31 | public LoggingFactoryBean getFactoryBean() {
32 | return factoryBean;
33 | }
34 |
35 | /**
36 | * create new traceId {@link LogTraceIdGenerator}
37 | *
38 | * @return traceId
39 | * @see DefaultLogTraceIdGenerator
40 | */
41 | @Override
42 | public String createTraceId() {
43 | return factoryBean.getTraceGenerator().createTraceId();
44 | }
45 |
46 | /**
47 | * create new spanId {@link LogSpanIdGenerator}
48 | *
49 | * @return spanId
50 | * @see DefaultLogSpanIdGenerator
51 | */
52 | @Override
53 | public String createSpanId() {
54 | return factoryBean.getSpanGenerator().createSpanId();
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/minbox-logging-admin-ui/src/main/frontend/components/sba-confirm-button.vue:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
24 |
25 |
26 |
52 |
53 |
54 |
61 |
--------------------------------------------------------------------------------
/minbox-logging-spring-context/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | minbox-logging-dependencies
7 | org.minbox.framework
8 | ${revision}
9 | ../minbox-logging-dependencies
10 |
11 | 4.0.0
12 | jar
13 | minbox-logging-spring-context
14 |
15 |
16 | org.springframework
17 | spring-webmvc
18 | true
19 |
20 |
21 | javax.servlet
22 | javax.servlet-api
23 | true
24 |
25 |
26 | org.minbox.framework
27 | minbox-logging-admin
28 | true
29 |
30 |
31 | org.minbox.framework
32 | minbox-logging-admin-ui
33 | true
34 |
35 |
36 | org.minbox.framework
37 | minbox-logging-client
38 | true
39 |
40 |
41 | org.apache.commons
42 | commons-lang3
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/minbox-logging-dependencies/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | minbox-logging
7 | org.minbox.framework
8 | ${revision}
9 |
10 | 4.0.0
11 | pom
12 | minbox-logging-dependencies
13 |
14 |
15 |
16 | org.minbox.framework
17 | minbox-logging-client
18 | ${project.version}
19 |
20 |
21 | org.minbox.framework
22 | minbox-logging-admin
23 | ${project.version}
24 |
25 |
26 | org.minbox.framework
27 | minbox-logging-admin-ui
28 | ${project.version}
29 |
30 |
31 | org.minbox.framework
32 | minbox-logging-core
33 | ${project.version}
34 |
35 |
36 | org.minbox.framework
37 | minbox-logging-spring-context
38 | ${project.version}
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/minbox-logging-admin-ui/src/main/frontend/utils/objToString.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014-2018 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import isEmpty from 'lodash/isEmpty';
18 | import isObject from 'lodash/isObject';
19 |
20 | const nonEmptyComplexValue = value => (Array.isArray(value) || isObject(value)) && !isEmpty(value);
21 |
22 | const objToString = (obj, indent = '') => {
23 | if (Array.isArray(obj)) {
24 | if (isEmpty(obj)) {
25 | return indent + '[]';
26 | }
27 |
28 | return obj.map(value => {
29 | if (nonEmptyComplexValue(value)) {
30 | return `${indent}-\n${objToString(value, indent + ' ')}`;
31 | }
32 | return `${indent}- ${objToString(value, '')}`;
33 | }).join('\n');
34 | }
35 |
36 | if (isObject(obj)) {
37 | if (isEmpty(obj)) {
38 | return indent + '{}';
39 | }
40 |
41 | return Object.entries(obj)
42 | .map(([key, value]) => {
43 | if (nonEmptyComplexValue(value)) {
44 | return `${indent}${key}:\n${objToString(value, indent + ' ')}`;
45 | }
46 | return `${indent}${key}: ${objToString(value, '')}`;
47 | })
48 | .join('\n');
49 | }
50 |
51 | if (obj === null) {
52 | return indent + 'null';
53 | }
54 |
55 | if (typeof obj === 'undefined' || obj === '') {
56 | return '';
57 | }
58 |
59 | return indent + obj;
60 | };
61 |
62 | export default objToString;
63 |
--------------------------------------------------------------------------------
/minbox-logging-client/src/main/java/org/minbox/framework/logging/client/admin/report/LoggingReportScheduled.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright [2019] [恒宇少年 - 于起宇]
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | */
17 |
18 | package org.minbox.framework.logging.client.admin.report;
19 |
20 | import org.minbox.framework.logging.client.LoggingFactoryBean;
21 |
22 | import java.util.concurrent.ScheduledExecutorService;
23 | import java.util.concurrent.ScheduledThreadPoolExecutor;
24 | import java.util.concurrent.TimeUnit;
25 |
26 | /**
27 | * ApiBoot Logging Report Scheduled
28 | *
29 | * @author 恒宇少年
30 | */
31 | public class LoggingReportScheduled {
32 | /**
33 | * the bean name of {@link LoggingReportScheduled}
34 | */
35 | public static final String BEAN_NAME = "loggingReportScheduled";
36 | /**
37 | * Scheduled Executor Service
38 | */
39 | private static final ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(10);
40 |
41 | /**
42 | * Scheduled Report
43 | *
44 | * @param factoryBean logging factory bean
45 | */
46 | public LoggingReportScheduled(LoggingFactoryBean factoryBean) {
47 | // scheduled report request logs
48 | executorService.scheduleAtFixedRate(() -> factoryBean.getLoggingAdminReport().report(),
49 | factoryBean.getReportInitialDelaySecond(), factoryBean.getReportIntervalSecond(), TimeUnit.SECONDS);
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/minbox-logging-samples/logging-admin-sample/src/main/java/org/minbox/framework/logging/admin/sample/CustomerReportEventListener.java:
--------------------------------------------------------------------------------
1 | package org.minbox.framework.logging.admin.sample;
2 |
3 | import org.minbox.framework.logging.admin.event.ReportLogEvent;
4 | import org.minbox.framework.logging.core.LoggingClientNotice;
5 | import org.minbox.framework.logging.core.MinBoxLog;
6 | import org.slf4j.Logger;
7 | import org.slf4j.LoggerFactory;
8 | import org.springframework.context.ApplicationEvent;
9 | import org.springframework.context.event.SmartApplicationListener;
10 | import org.springframework.stereotype.Component;
11 |
12 | import java.util.List;
13 |
14 | /**
15 | * 自定义上报日志事件{@link ReportLogEvent}监听
16 | *
17 | * @author 恒宇少年
18 | */
19 | @Component
20 | public class CustomerReportEventListener implements SmartApplicationListener {
21 | /**
22 | * logger instance
23 | */
24 | static Logger logger = LoggerFactory.getLogger(CustomerReportEventListener.class);
25 |
26 | /**
27 | * 判断事件类型为{@link ReportLogEvent}
28 | *
29 | * @param eventType
30 | * @return
31 | */
32 | @Override
33 | public boolean supportsEventType(Class extends ApplicationEvent> eventType) {
34 | return ReportLogEvent.class == eventType;
35 | }
36 |
37 | /**
38 | * 自定义处理业务
39 | * Client一次可上报多条日志{@link MinBoxLog}信息
40 | *
41 | * @param event {@link ReportLogEvent}
42 | */
43 | @Override
44 | public void onApplicationEvent(ApplicationEvent event) {
45 | ReportLogEvent reportLogEvent = (ReportLogEvent) event;
46 | LoggingClientNotice loggingClientNotice = reportLogEvent.getLogClientNotice();
47 |
48 | // MinBoxLog 日志列表
49 | List logs = loggingClientNotice.getLoggers();
50 |
51 | logger.debug("上报日志服务:{},IP地址:{},端口号:{},日志列表:", loggingClientNotice.getClientServiceId(),
52 | loggingClientNotice.getClientServiceIp(),
53 | loggingClientNotice.getClientServicePort(),
54 | logs);
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/minbox-logging-admin-ui/src/main/frontend/shell/index.vue:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
61 |
--------------------------------------------------------------------------------
/minbox-logging-admin/src/main/java/org/minbox/framework/logging/admin/storage/LoggingDefaultStorage.java:
--------------------------------------------------------------------------------
1 | package org.minbox.framework.logging.admin.storage;
2 |
3 | import org.minbox.framework.logging.core.GlobalLog;
4 | import org.minbox.framework.logging.core.MinBoxLog;
5 | import org.minbox.framework.logging.core.response.LoggingResponse;
6 | import org.minbox.framework.logging.core.response.ServiceResponse;
7 |
8 | import java.sql.SQLException;
9 | import java.time.LocalDateTime;
10 | import java.util.List;
11 |
12 | /**
13 | * The {@link LoggingStorage} default support
14 | *
15 | * @author 恒宇少年
16 | */
17 | public class LoggingDefaultStorage implements LoggingStorage {
18 | @Override
19 | public String insertGlobalLog(String requestLogId, GlobalLog log) throws SQLException {
20 | return null;
21 | }
22 |
23 | @Override
24 | public String insertLog(String serviceDetailId, MinBoxLog log) throws SQLException {
25 | return null;
26 | }
27 |
28 | @Override
29 | public String insertServiceDetail(String serviceId, String serviceIp, int servicePort) throws SQLException {
30 | return null;
31 | }
32 |
33 | @Override
34 | public String selectServiceDetailId(String serviceId, String serviceIp, int servicePort) throws SQLException {
35 | return null;
36 | }
37 |
38 | @Override
39 | public List findAllService() throws SQLException {
40 | return null;
41 | }
42 |
43 | @Override
44 | public List findTopList(int topCount) throws SQLException {
45 | return null;
46 | }
47 |
48 | @Override
49 | public void updateLastReportTime(String serviceDetailId) throws SQLException {
50 |
51 | }
52 |
53 | @Override
54 | public long cleanupExpiredGlobalLogs(LocalDateTime effectiveDeadlineTime) throws SQLException {
55 | return 0L;
56 | }
57 |
58 | @Override
59 | public long cleanupExpiredRequestLogs(LocalDateTime effectiveDeadlineTime) throws SQLException {
60 | return 0L;
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/minbox-logging-admin-ui/src/main/frontend/utils/axios.spec.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014-2018 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import {redirectOn401} from './axios';
18 |
19 | describe('redirectOn401', () => {
20 | it('should not redirect on 500', async () => {
21 | window.location.assign = jest.fn();
22 |
23 | const error = {
24 | response: {
25 | status: 500
26 | }
27 | };
28 |
29 | try {
30 | await redirectOn401()(error);
31 | } catch (e) {
32 | expect(e).toBe(error);
33 | }
34 |
35 | expect(window.location.assign).not.toBeCalled();
36 | });
37 |
38 | it('should redirect on 401', async () => {
39 | window.location.assign = jest.fn();
40 |
41 | const error = {
42 | response: {
43 | status: 401
44 | }
45 | };
46 |
47 | try {
48 | await redirectOn401()(error);
49 | } catch (e) {
50 | expect(e).toBe(error);
51 | }
52 |
53 | expect(window.location.assign).toBeCalledWith('login?redirectTo=http%3A%2F%2Fexample.com%2F');
54 | });
55 |
56 | it('should not redirect on 401 for predicate yields false', async () => {
57 | window.location.assign = jest.fn();
58 |
59 | const error = {
60 | response: {
61 | status: 401
62 | }
63 | };
64 |
65 | try {
66 | await redirectOn401(() => false)(error);
67 | } catch (e) {
68 | expect(e).toBe(error);
69 | }
70 |
71 | expect(window.location.assign).not.toBeCalled();
72 | });
73 | });
74 |
--------------------------------------------------------------------------------
/minbox-logging-client/src/main/java/org/minbox/framework/logging/client/cache/LoggingCache.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright [2019] [恒宇少年 - 于起宇]
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | */
17 |
18 | package org.minbox.framework.logging.client.cache;
19 |
20 | import org.minbox.framework.logging.client.MinBoxLoggingException;
21 | import org.minbox.framework.logging.core.MinBoxLog;
22 |
23 | import java.util.List;
24 |
25 | /**
26 | * ApiBoot Logging Cache
27 | *
28 | * @author 恒宇少年
29 | */
30 | public interface LoggingCache {
31 | /**
32 | * Cache Single MinBoxLog
33 | *
34 | * @param log MinBoxLog
35 | * @throws MinBoxLoggingException Logging Exception
36 | */
37 | void cache(MinBoxLog log) throws MinBoxLoggingException;
38 |
39 | /**
40 | * Get Any One MinBoxLog
41 | *
42 | * @return MinBoxLog
43 | * @throws MinBoxLoggingException Logging Exception
44 | */
45 | MinBoxLog getAnyOne() throws MinBoxLoggingException;
46 |
47 | /**
48 | * Gets the specified number of MinBoxLog
49 | *
50 | * @param count get count number
51 | * @return MinBoxLog Collection
52 | * @throws MinBoxLoggingException Logging Exception
53 | */
54 | List getLogs(int count) throws MinBoxLoggingException;
55 |
56 | /**
57 | * Gets All Of MinBoxLog
58 | *
59 | * @return MinBoxLog Collection
60 | * @throws MinBoxLoggingException Logging Exception
61 | */
62 | List getAll() throws MinBoxLoggingException;
63 | }
64 |
--------------------------------------------------------------------------------
/minbox-logging-client/src/main/java/org/minbox/framework/logging/client/LogThreadLocal.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright [2019] [恒宇少年 - 于起宇]
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | */
17 |
18 | package org.minbox.framework.logging.client;
19 |
20 | import com.alibaba.ttl.TransmittableThreadLocal;
21 | import org.minbox.framework.logging.core.MinBoxLog;
22 |
23 | /**
24 | * Using threadLocal to store log objects in multithreaded situations
25 | *
26 | * @author 恒宇少年
27 | */
28 | public class LogThreadLocal {
29 | /**
30 | * The Request Logs
31 | * Solve the problem of the {@link MinBoxLog} object of the child parent thread
32 | * https://gitee.com/minbox-projects/minbox-logging/issues/I11QKJ
33 | *
34 | * @see TransmittableThreadLocal
35 | * @see MinBoxLog
36 | */
37 | private static final TransmittableThreadLocal LOGS = new TransmittableThreadLocal<>();
38 |
39 | /**
40 | * Get This Thread ApiBoot Log Object Instance
41 | *
42 | * @return This Thread ApiBoot Log
43 | */
44 | public static MinBoxLog get() {
45 | return LOGS.get();
46 | }
47 |
48 | /**
49 | * Set This Thread ApiBoot Log Object Instance
50 | *
51 | * @param minBoxLog This Thread ApiBoot Log
52 | */
53 | public static void set(MinBoxLog minBoxLog) {
54 | LOGS.set(minBoxLog);
55 | }
56 |
57 | /**
58 | * Remove This Thread ApiBoot Log Object Instance
59 | */
60 | public static void remove() {
61 | LOGS.remove();
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/minbox-logging-admin-ui/src/main/frontend/components/sba-status.spec.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014-2018 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import {mount} from '@vue/test-utils';
18 | import moment from 'moment';
19 | import sbaStatus from './sba-status';
20 |
21 | moment.now = () => +new Date(1318781879406);
22 |
23 | describe('application-status', () => {
24 |
25 | const testSnapshotForStatus = (status, date) => {
26 | const wrapper = mount(sbaStatus, {
27 | propsData: {
28 | status,
29 | date
30 | },
31 | stubs: {
32 | 'font-awesome-icon': true
33 | }
34 | });
35 | expect(wrapper.vm.$el).toMatchSnapshot();
36 | };
37 |
38 | it('should match the snapshot with status UP with Timestamp', () => {
39 | testSnapshotForStatus('UP', 1318781000000);
40 | });
41 |
42 | it('should match the snapshot with status RESTRICTED', () => {
43 | testSnapshotForStatus('RESTRICTED');
44 | });
45 |
46 | it('should match the snapshot with status OUT_OF_SERVICE', () => {
47 | testSnapshotForStatus('OUT_OF_SERVICE');
48 | });
49 |
50 | it('should match the snapshot with status DOWN', () => {
51 | testSnapshotForStatus('DOWN');
52 | });
53 |
54 | it('should match the snapshot with status UNKNOWN', () => {
55 | testSnapshotForStatus('UNKNOWN');
56 | });
57 |
58 | it('should match the snapshot with status OFFLINE', () => {
59 | testSnapshotForStatus('OFFLINE');
60 | });
61 |
62 | it('should match the snapshot with custom status', () => {
63 | testSnapshotForStatus('?');
64 | });
65 |
66 | });
67 |
--------------------------------------------------------------------------------
/minbox-logging-client/src/main/java/org/minbox/framework/logging/client/admin/discovery/lb/support/RandomWeightedStrategy.java:
--------------------------------------------------------------------------------
1 | package org.minbox.framework.logging.client.admin.discovery.lb.support;
2 |
3 | import org.minbox.framework.logging.client.MinBoxLoggingException;
4 | import org.minbox.framework.logging.client.admin.discovery.lb.LoadBalanceNode;
5 | import org.springframework.util.ObjectUtils;
6 |
7 | import java.util.List;
8 | import java.util.SortedMap;
9 | import java.util.TreeMap;
10 |
11 | /**
12 | * The {@link org.minbox.framework.logging.client.admin.discovery.lb.LoadBalanceStrategy} random strategy
13 | *
14 | * @author 恒宇少年
15 | * @see DefaultLoadBalanceStrategy
16 | * @see org.minbox.framework.logging.client.admin.discovery.lb.LoadBalanceStrategy
17 | */
18 | public class RandomWeightedStrategy extends DefaultLoadBalanceStrategy {
19 | /**
20 | * logging admin node list
21 | * {@link LoadBalanceNode}
22 | */
23 | private TreeMap nodes = new TreeMap();
24 |
25 | /**
26 | * lookup logging admin load-balanced address {@link LoadBalanceNode#getAddress()}
27 | * Lookup according to random weight admin address
28 | * get firstKey by {@link SortedMap#tailMap(Object)}
29 | *
30 | * @param adminAddress logging admin address array
31 | * @return Load-balanced addresses
32 | * @throws MinBoxLoggingException MinBox Logging Exception
33 | */
34 | @Override
35 | public String lookup(String[] adminAddress) throws MinBoxLoggingException {
36 | List loadBalanceNodes = initNodeList(adminAddress);
37 | loadBalanceNodes.stream().forEach(node -> {
38 | double lastWeight = this.nodes.size() == 0 ? 0 : this.nodes.lastKey().doubleValue();
39 | this.nodes.put(node.getInitWeight() + lastWeight, node);
40 | });
41 | Double randomWeight = this.nodes.lastKey() * Math.random();
42 | SortedMap tailMap = this.nodes.tailMap(randomWeight, false);
43 | if (ObjectUtils.isEmpty(tailMap)) {
44 | throw new MinBoxLoggingException("No load balancing node was found");
45 | }
46 | return this.nodes.get(tailMap.firstKey()).getAddress();
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/minbox-logging-client/src/main/java/org/minbox/framework/logging/client/http/openfeign/LoggingOpenFeignInterceptor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright [2019] [恒宇少年 - 于起宇]
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | */
17 |
18 | package org.minbox.framework.logging.client.http.openfeign;
19 |
20 | import feign.RequestInterceptor;
21 | import feign.RequestTemplate;
22 | import org.minbox.framework.logging.client.LoggingConstant;
23 | import org.minbox.framework.logging.client.LogThreadLocal;
24 | import org.minbox.framework.logging.core.MinBoxLog;
25 | import org.slf4j.Logger;
26 | import org.slf4j.LoggerFactory;
27 | import org.springframework.util.ObjectUtils;
28 |
29 | /**
30 | * Openfeign Request Interceptor
31 | * Requests initiated by openfeign carry ApiBoot TraceId and spanId
32 | *
33 | * @author 恒宇少年
34 | */
35 | public class LoggingOpenFeignInterceptor implements RequestInterceptor {
36 | /**
37 | * logger instance
38 | */
39 | static Logger logger = LoggerFactory.getLogger(LoggingOpenFeignInterceptor.class);
40 |
41 | @Override
42 | public void apply(RequestTemplate requestTemplate) {
43 | MinBoxLog log = LogThreadLocal.get();
44 | if (!ObjectUtils.isEmpty(log)) {
45 | requestTemplate.header(LoggingConstant.HEADER_NAME_TRACE_ID, log.getTraceId());
46 | requestTemplate.header(LoggingConstant.HEADER_NAME_PARENT_SPAN_ID, log.getSpanId());
47 | logger.debug("RequestUri:{}, Method:{},Setting Logging TraceId:{},SpanId:{} With Openfeign.",
48 | requestTemplate.url(), requestTemplate.request().httpMethod().toString(), log.getTraceId(), log.getSpanId());
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/minbox-logging-admin-ui/src/main/frontend/viewRegistry.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014-2019 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import {VIEW_GROUP} from './views';
18 |
19 | const createTextVNode = (label) => {
20 | return {
21 | render() {
22 | return this._v(this.$t(label))
23 | }
24 | }
25 | };
26 |
27 | export default class ViewRegistry {
28 | constructor() {
29 | this._views = [];
30 | this._redirects = [];
31 | }
32 |
33 | get views() {
34 | return this._views;
35 | }
36 |
37 | get routes() {
38 | return [
39 | ...this._toRoutes(this._views, v => v.path && !v.parent),
40 | ...this._redirects
41 | ]
42 | }
43 |
44 | addView(...views) {
45 | views.forEach(view => this._addView(view));
46 | }
47 |
48 | addRedirect(path, redirect) {
49 | if (typeof redirect === 'string') {
50 | this._redirects.push({path, redirect: {name: redirect}});
51 | } else {
52 | this._redirects.push({path, redirect});
53 | }
54 | }
55 |
56 | _addView(view) {
57 | if (view.label && !view.handle) {
58 | view.handle = createTextVNode(view.label);
59 | }
60 | if (!view.group) {
61 | view.group = VIEW_GROUP.NONE;
62 | }
63 |
64 | this._views.push(view);
65 | }
66 |
67 | _toRoutes(views, filter) {
68 | return views.filter(filter).map(
69 | p => {
70 | const children = this._toRoutes(views, v => v.parent === p.name);
71 | return ({
72 | path: p.path,
73 | name: children.length === 0 ? p.name : undefined,
74 | component: p.component,
75 | props: p.props,
76 | meta: {view: p},
77 | children
78 | });
79 | }
80 | )
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/minbox-logging-samples/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | minbox-logging
7 | org.minbox.framework
8 | ${revision}
9 |
10 | 4.0.0
11 | pom
12 |
13 | true
14 | true
15 | true
16 | 2.6.6
17 | 2.3.7
18 |
19 |
20 | Logging Client、Logging Admin使用示例
21 |
22 |
23 | logging-client-sample
24 | logging-admin-sample
25 |
26 | minbox-logging-samples
27 |
28 |
29 |
30 |
31 | org.springframework.boot
32 | spring-boot-dependencies
33 | ${spring-boot.version}
34 | pom
35 | import
36 |
37 |
38 |
39 | org.minbox.framework
40 | minbox-logging-dependencies
41 | ${project.version}
42 | import
43 | pom
44 |
45 |
46 |
47 | org.minbox.framework
48 | api-boot-dependencies
49 | ${api-boot.version}
50 | pom
51 | import
52 |
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/minbox-logging-client/src/main/java/org/minbox/framework/logging/client/interceptor/webflux/LoggingWebFluxInterceptor.java:
--------------------------------------------------------------------------------
1 | package org.minbox.framework.logging.client.interceptor.webflux;
2 |
3 | import org.minbox.framework.logging.client.LoggingFactoryBean;
4 | import org.minbox.framework.logging.client.interceptor.LoggingAbstractInterceptor;
5 | import org.minbox.framework.util.UrlUtils;
6 | import org.slf4j.Logger;
7 | import org.slf4j.LoggerFactory;
8 | import org.springframework.http.server.reactive.ServerHttpRequest;
9 | import org.springframework.web.server.ServerWebExchange;
10 | import org.springframework.web.server.WebFilter;
11 | import org.springframework.web.server.WebFilterChain;
12 | import reactor.core.publisher.Mono;
13 |
14 | import java.util.List;
15 |
16 | /**
17 | * {@link org.springframework.web.server.WebFilter}
18 | *
19 | * @author 恒宇少年
20 | */
21 | public class LoggingWebFluxInterceptor extends LoggingAbstractInterceptor implements WebFilter {
22 | /**
23 | * logger instance
24 | */
25 | static Logger logger = LoggerFactory.getLogger(LoggingWebFluxInterceptor.class);
26 | /**
27 | * {@link LoggingFactoryBean}
28 | */
29 | private LoggingFactoryBean factoryBean;
30 |
31 | public LoggingWebFluxInterceptor(LoggingFactoryBean factoryBean) {
32 | super(factoryBean);
33 | this.factoryBean = factoryBean;
34 | }
35 |
36 | /**
37 | * Intercept requests and generate logs
38 | *
39 | * @param exchange {@link ServerWebExchange}
40 | * @param chain {@link WebFilterChain}
41 | * @return {@link Mono}
42 | */
43 | @Override
44 | public Mono filter(ServerWebExchange exchange, WebFilterChain chain) {
45 | ServerHttpRequest request = exchange.getRequest();
46 | boolean isIgnore = checkUriIsIgnore(request);
47 | if (isIgnore) {
48 | return chain.filter(exchange);
49 | }
50 | return chain.filter(exchange);
51 | }
52 |
53 | /**
54 | * check request uri is ignore {@link UrlUtils#isIgnore(List, String)}
55 | *
56 | * @param request {@link ServerHttpRequest}
57 | * @return uri is ignore
58 | */
59 | private boolean checkUriIsIgnore(ServerHttpRequest request) {
60 | String uri = request.getURI().getPath();
61 | return UrlUtils.isIgnore(factoryBean.getIgnorePaths(), uri);
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/minbox-logging-admin-ui/src/main/frontend/components/__snapshots__/sba-status.spec.js.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`application-status should match the snapshot with custom status 1`] = `
4 |
7 |
10 |
11 |
12 |
13 | `;
14 |
15 | exports[`application-status should match the snapshot with status DOWN 1`] = `
16 |
19 |
23 |
24 |
25 |
26 | `;
27 |
28 | exports[`application-status should match the snapshot with status OFFLINE 1`] = `
29 |
32 |
36 |
37 |
38 |
39 | `;
40 |
41 | exports[`application-status should match the snapshot with status OUT_OF_SERVICE 1`] = `
42 |
45 |
49 |
50 |
51 |
52 | `;
53 |
54 | exports[`application-status should match the snapshot with status RESTRICTED 1`] = `
55 |
58 |
62 |
63 |
64 |
65 | `;
66 |
67 | exports[`application-status should match the snapshot with status UNKNOWN 1`] = `
68 |
71 |
75 |
76 |
77 |
78 | `;
79 |
80 | exports[`application-status should match the snapshot with status UP with Timestamp 1`] = `
81 |
84 |
88 |
89 |
90 | 14m
91 |
92 |
93 | `;
94 |
--------------------------------------------------------------------------------
/minbox-logging-core/src/main/java/org/minbox/framework/logging/core/mapping/LoggingRequestMappingHandlerMapping.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright [2019] [恒宇少年 - 于起宇]
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | */
17 |
18 | package org.minbox.framework.logging.core.mapping;
19 |
20 | import org.minbox.framework.logging.core.annotation.Endpoint;
21 | import org.slf4j.Logger;
22 | import org.slf4j.LoggerFactory;
23 | import org.springframework.core.annotation.AnnotationUtils;
24 | import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
25 |
26 | import javax.annotation.PostConstruct;
27 |
28 |
29 | /**
30 | * ApiBoot Logging RequestMapping Handler
31 | *
32 | * @author 恒宇少年
33 | */
34 |
35 | public class LoggingRequestMappingHandlerMapping extends RequestMappingHandlerMapping {
36 | /**
37 | * The bean name of {@link LoggingRequestMappingHandlerMapping}
38 | */
39 | public static final String BEAN_NAME = "loggingRequestMappingHandlerMapping";
40 | /**
41 | * logger instance
42 | */
43 | static Logger logger = LoggerFactory.getLogger(LoggingRequestMappingHandlerMapping.class);
44 |
45 | @PostConstruct
46 | public void setOrder() {
47 | super.setOrder(0);
48 | }
49 |
50 | /**
51 | * Only Endpoint Class with @Endpoint annotation is processed
52 | *
53 | * @param beanType endpoint bean type class
54 | * @return is handler
55 | */
56 | @Override
57 | protected boolean isHandler(Class> beanType) {
58 | boolean isEndpoint = AnnotationUtils.findAnnotation(beanType, Endpoint.class) != null;
59 | if (isEndpoint) {
60 | logger.info("Load ApiBoot Logging Endpoint,BeanType:[{}]", beanType.getName());
61 | }
62 | return isEndpoint;
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/minbox-logging-client/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | minbox-logging-dependencies
7 | org.minbox.framework
8 | ${revision}
9 | ../minbox-logging-dependencies
10 |
11 | 4.0.0
12 | jar
13 | minbox-logging-client
14 |
15 | 2.11.5
16 | 3.1.1
17 |
18 |
19 |
20 | org.minbox.framework
21 | minbox-logging-core
22 | ${project.version}
23 |
24 |
25 | javax.servlet
26 | javax.servlet-api
27 | true
28 |
29 |
30 | org.springframework
31 | spring-webmvc
32 | true
33 |
34 |
35 | org.springframework
36 | spring-webflux
37 | true
38 |
39 |
40 | org.springframework.cloud
41 | spring-cloud-starter-openfeign
42 | ${openfeign.version}
43 | true
44 |
45 |
46 | org.minbox.framework
47 | minbox-sequence
48 |
49 |
50 | com.alibaba
51 | transmittable-thread-local
52 | ${transmittable-thread-local.version}
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/minbox-logging-admin-ui/src/main/frontend/components/sba-status.vue:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
19 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
60 |
61 |
94 |
--------------------------------------------------------------------------------
/minbox-logging-core/src/main/java/org/minbox/framework/logging/core/LoggingClientNotice.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright [2019] [恒宇少年 - 于起宇]
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | */
17 |
18 | package org.minbox.framework.logging.core;
19 |
20 | import lombok.Data;
21 |
22 | import java.io.Serializable;
23 | import java.util.ArrayList;
24 | import java.util.List;
25 |
26 | /**
27 | * ApiBoot Logging Client Notice Object
28 | *
29 | * @author 恒宇少年
30 | */
31 | @Data
32 | public class LoggingClientNotice implements Serializable {
33 | /**
34 | * Client Service Id
35 | */
36 | private String clientServiceId;
37 | /**
38 | * Client Service Ip Address
39 | */
40 | private String clientServiceIp;
41 | /**
42 | * Client Service Port
43 | */
44 | private Integer clientServicePort;
45 | /**
46 | * Report Time Millis
47 | */
48 | private Long reportTimeMillis = System.currentTimeMillis();
49 | /**
50 | * ApiBoot Logging Request Log
51 | */
52 | private List loggers = new ArrayList<>();
53 |
54 | /**
55 | * Create new {@link LoggingClientNotice} instance
56 | *
57 | * @param clientServiceId {@link #clientServiceId}
58 | * @param clientServiceIp {@link #clientServiceIp}
59 | * @param clientServicePort {@link #clientServicePort}
60 | * @param loggers {@link #loggers}
61 | * @return {@link LoggingClientNotice}
62 | */
63 | public static LoggingClientNotice instance(
64 | String clientServiceId, String clientServiceIp, Integer clientServicePort, List loggers) {
65 | LoggingClientNotice notice = new LoggingClientNotice();
66 | notice.setClientServiceId(clientServiceId);
67 | notice.setClientServiceIp(clientServiceIp);
68 | notice.setClientServicePort(clientServicePort);
69 | notice.setLoggers(loggers);
70 | return notice;
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/minbox-logging-admin-ui/src/main/frontend/utils/autolink.spec.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014-2018 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import autolink, {Autolink} from './autolink'
18 |
19 | describe('autolink should', () => {
20 | it('return the input string for normal text', () => {
21 | const str = 'This is just a normal text containing no hyperlinks';
22 | expect(autolink(str)).toBe(str);
23 | });
24 |
25 | it('return string with anchor tag for the hyperlink', () => {
26 | const str = 'Please visit http://example.com.';
27 | expect(autolink(str)).toBe('Please visit http://example.com.');
28 | });
29 |
30 | it('return string with anchor tag with shortened text for the hyperlink', () => {
31 | const str = 'Please visit http://extraordinary.com/very/very/log/hyperlink.';
32 |
33 | const customAutolink = new Autolink({
34 | truncate: {
35 | length: 30,
36 | location: 'smart'
37 | },
38 | });
39 | expect(customAutolink(str)).toBe('Please visit extraordinary.com/very…rlink.');
40 | });
41 |
42 | it('return string with anchor for hyperlinks in dense json', () => {
43 | const str = '{"name":"John Smith","links":[{"rel":"random-link1","href":"https://localhost:8000/api/123/query?action=do_something&age=21","hreflang":null,"media":null,"title":null,"type":null,"deprecation":null}]}';
44 | expect(autolink(str)).toBe('{"name":"John Smith","links":[{"rel":"random-link1","href":"https://localhost:8000/api/123/query?action=do_something&age=21","hreflang":null,"media":null,"title":null,"type":null,"deprecation":null}]}');
45 | });
46 | });
47 |
--------------------------------------------------------------------------------
/minbox-logging-admin-ui/src/main/frontend/components/sba-panel.vue:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
19 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
69 |
70 |
91 |
--------------------------------------------------------------------------------
/minbox-logging-admin-ui/src/main/frontend/utils/logtail.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014-2019 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import {concatMap, EMPTY, of, timer} from '@/utils/rxjs';
18 |
19 | export default (getFn, interval, initialSize = 300 * 1024) => {
20 | let range = `bytes=-${initialSize}`;
21 | let size = 0;
22 |
23 | return timer(0, interval)
24 | .pipe(
25 | concatMap(() => getFn({headers: {range, 'Accept': 'text/plain'}})),
26 | concatMap(response => {
27 | const initial = size === 0;
28 | const contentLength = response.data.length;
29 | if (response.status === 200) {
30 | if (!initial) {
31 | throw 'Expected 206 - Partial Content on subsequent requests.';
32 | }
33 | size = contentLength;
34 | } else if (response.status === 206) {
35 | size = parseInt(response.headers['content-range'].split('/')[1]);
36 | } else {
37 | throw 'Unexpected response status: ' + response.status;
38 | }
39 |
40 | // Reload the last byte to avoid a 416: Range unsatisfiable.
41 | // If the response has length = 1 the file hasn't beent changed.
42 | // If the response status is 416 the logfile has been truncated.
43 | range = `bytes=${size - 1}-`;
44 |
45 | let addendum = null;
46 | let skipped = 0;
47 |
48 | if (initial) {
49 | if (contentLength >= size) {
50 | addendum = response.data;
51 | } else {
52 | // In case of a partial response find the first line break.
53 | addendum = response.data.substring(response.data.indexOf('\n') + 1);
54 | skipped = size - addendum.length;
55 | }
56 | } else if (response.data.length > 1) {
57 | // Remove the first byte which has been part of the previos response.
58 | addendum = response.data.substring(1);
59 | }
60 |
61 | return addendum ? of({
62 | totalBytes: size,
63 | skipped,
64 | addendum
65 | }) : EMPTY;
66 | })
67 | );
68 | }
69 |
--------------------------------------------------------------------------------
/minbox-logging-admin-ui/src/main/frontend/utils/rxjs.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014-2019 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import {defer} from 'rxjs/internal/observable/defer';
18 | import {tap} from 'rxjs/internal/operators/tap';
19 |
20 | export {throwError} from 'rxjs/internal/observable/throwError';
21 | export {of} from 'rxjs/internal/observable/of';
22 | export {defer} from 'rxjs/internal/observable/defer';
23 | export {concat} from 'rxjs/internal/observable/concat';
24 | export {EMPTY} from 'rxjs/internal/observable/empty';
25 | export {from} from 'rxjs/internal/observable/from';
26 | export {timer} from 'rxjs/internal/observable/timer';
27 | export {Observable} from 'rxjs/internal/Observable';
28 | export {Subject} from 'rxjs/internal/Subject';
29 | export {animationFrame as animationFrameScheduler} from 'rxjs/internal/scheduler/animationFrame';
30 | export {concatMap} from 'rxjs/internal/operators/concatMap';
31 | export {delay} from 'rxjs/internal/operators/delay';
32 | export {debounceTime} from 'rxjs/internal/operators/debounceTime';
33 | export {merge} from 'rxjs/internal/operators/merge';
34 | export {map} from 'rxjs/internal/operators/map';
35 | export {retryWhen} from 'rxjs/internal/operators/retryWhen';
36 | export {tap} from 'rxjs/internal/operators/tap';
37 | export {filter} from 'rxjs/internal/operators/filter';
38 | export {concatAll} from 'rxjs/internal/operators/concatAll';
39 | export {ignoreElements} from 'rxjs/internal/operators/ignoreElements';
40 | export {bufferTime} from 'rxjs/internal/operators/bufferTime';
41 | export {finalize} from 'rxjs/internal/operators/finalize';
42 |
43 | export const doOnSubscribe = cb => source =>
44 | defer(() => {
45 | cb();
46 | return source
47 | });
48 |
49 | export const listen = (cb, execDelay = 150) => source => {
50 | let handle = null;
51 | return source.pipe(
52 | doOnSubscribe(() => handle = setTimeout(() => cb('executing'), execDelay)),
53 | tap({
54 | complete: () => {
55 | handle && clearTimeout(handle);
56 | cb('completed');
57 | },
58 | error: (error) => {
59 | console.warn('Operation failed:', error);
60 | handle && clearTimeout(handle);
61 | cb('failed');
62 | }
63 | })
64 | )
65 | };
66 |
--------------------------------------------------------------------------------
/minbox-logging-client/src/main/java/org/minbox/framework/logging/client/notice/support/LoggingAdminNotice.java:
--------------------------------------------------------------------------------
1 | package org.minbox.framework.logging.client.notice.support;
2 |
3 | import org.minbox.framework.logging.client.LoggingFactoryBean;
4 | import org.minbox.framework.logging.client.admin.report.LoggingAdminReport;
5 | import org.minbox.framework.logging.client.cache.LoggingCache;
6 | import org.minbox.framework.logging.client.notice.LoggingNotice;
7 | import org.minbox.framework.logging.core.MinBoxLog;
8 | import org.minbox.framework.logging.core.ReportAway;
9 | import org.slf4j.Logger;
10 | import org.slf4j.LoggerFactory;
11 | import org.springframework.lang.Nullable;
12 |
13 | import java.util.Arrays;
14 |
15 | /**
16 | * Logging admin notification
17 | *
18 | * @author 恒宇少年
19 | */
20 | public class LoggingAdminNotice implements LoggingNotice {
21 | /**
22 | * the bean name of {@link LoggingAdminNotice}
23 | */
24 | public static final String BEAN_NAME = "loggingAdminNotice";
25 | /**
26 | * logger instance
27 | */
28 | static Logger logger = LoggerFactory.getLogger(LoggingAdminNotice.class);
29 |
30 | /**
31 | * logging factory bean
32 | * {@link LoggingFactoryBean}
33 | * {@link LoggingCache}
34 | * {@link LoggingAdminReport}
35 | */
36 | @Nullable
37 | private LoggingFactoryBean factoryBean;
38 |
39 | /**
40 | * Injecting {@link LoggingFactoryBean} through constructor injection
41 | *
42 | * @param factoryBean {@link LoggingFactoryBean}
43 | */
44 | public LoggingAdminNotice(@Nullable LoggingFactoryBean factoryBean) {
45 | this.factoryBean = factoryBean;
46 | }
47 |
48 | /**
49 | * if just report away,execute report logs to admin
50 | * if timing report away,cache logs to {@link LoggingCache} support,
51 | * wait for {@link org.minbox.framework.logging.client.admin.report.LoggingReportScheduled} execute report
52 | *
53 | * @param minBoxLog ApiBoot Log
54 | */
55 | @Override
56 | public void notice(MinBoxLog minBoxLog) {
57 | ReportAway reportAway = factoryBean.getReportAway();
58 | switch (reportAway) {
59 | case just:
60 | LoggingAdminReport loggingAdminReport = factoryBean.getLoggingAdminReport();
61 | loggingAdminReport.report(Arrays.asList(minBoxLog));
62 | break;
63 | case timing:
64 | factoryBean.getLoggingCache().cache(minBoxLog);
65 | logger.debug("Cache Request Logging Complete.");
66 | break;
67 | default:
68 | logger.warn("Unsupported reporting away.");
69 | break;
70 | }
71 | }
72 |
73 | @Override
74 | public int getOrder() {
75 | return HIGHEST_PRECEDENCE + 1;
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/minbox-logging-client/src/main/java/org/minbox/framework/logging/client/http/rest/LoggingRestTemplateInterceptor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright [2019] [恒宇少年 - 于起宇]
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | */
17 |
18 | package org.minbox.framework.logging.client.http.rest;
19 |
20 | import org.minbox.framework.logging.client.LoggingConstant;
21 | import org.minbox.framework.logging.client.LogThreadLocal;
22 | import org.minbox.framework.logging.core.MinBoxLog;
23 | import org.slf4j.Logger;
24 | import org.slf4j.LoggerFactory;
25 | import org.springframework.http.HttpRequest;
26 | import org.springframework.http.client.ClientHttpRequestExecution;
27 | import org.springframework.http.client.ClientHttpRequestInterceptor;
28 | import org.springframework.http.client.ClientHttpResponse;
29 | import org.springframework.util.ObjectUtils;
30 |
31 | import java.io.IOException;
32 |
33 |
34 | /**
35 | * ApiBoot Logging RestTemplate Interceptor
36 | * Pass-through traceId and spanId
37 | *
38 | * @author 恒宇少年
39 | */
40 | public class LoggingRestTemplateInterceptor implements ClientHttpRequestInterceptor {
41 | /**
42 | * logger instance
43 | */
44 | static Logger logger = LoggerFactory.getLogger(LoggingRestTemplateInterceptor.class);
45 |
46 | /**
47 | * Request Exception
48 | *
49 | * @param request {@link HttpRequest}
50 | * @param body Request Body
51 | * @param execution Execute
52 | * @return {@link ClientHttpResponse}
53 | * @throws IOException
54 | */
55 | @Override
56 | public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
57 | MinBoxLog log = LogThreadLocal.get();
58 | if (!ObjectUtils.isEmpty(log)) {
59 | request.getHeaders().add(LoggingConstant.HEADER_NAME_TRACE_ID, log.getTraceId());
60 | request.getHeaders().add(LoggingConstant.HEADER_NAME_PARENT_SPAN_ID, log.getSpanId());
61 | logger.debug("RequestUri:{}, Method:{},Setting Logging TraceId:{},SpanId:{} With RestTemplate.",
62 | request.getURI().getPath(), request.getMethod().toString(), log.getTraceId(), log.getSpanId());
63 | }
64 | return execution.execute(request, body);
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/minbox-logging-admin-ui/src/main/frontend/services/application.spec.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014-2019 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import {convertBody, hasMatchingContentType, throwOnError} from './application';
18 |
19 | describe('hasMatchingContentType', () => {
20 | it('should match content-type', () => {
21 | const matches = hasMatchingContentType(
22 | 'application/json;charset=UTF-8',
23 | ['application/vnd.spring-boot.actuator.v1+json', 'application/json']
24 | );
25 | expect(matches).toBe(true);
26 | });
27 |
28 | it('should not match content-types', () => {
29 | const matches = hasMatchingContentType(
30 | 'application/html;charset=UTF-8',
31 | ['application/vnd.spring-boot.actuator.v1+json', 'application/json']
32 | );
33 | expect(matches).toBe(false);
34 | });
35 |
36 | it('should not match undefined', () => {
37 | const matches = hasMatchingContentType(
38 | undefined,
39 | ['application/vnd.spring-boot.actuator.v1+json', 'application/json']
40 | );
41 | expect(matches).toBe(false);
42 | });
43 | });
44 |
45 | describe('throwOnError', () => {
46 | it('should not throw on no response', () => {
47 | throwOnError([])
48 | });
49 |
50 | it('should not throw on no error', () => {
51 | throwOnError([{status: 200}, {status: 100}, {status: 302}])
52 | });
53 |
54 | it('should not throw on error', () => {
55 | expect(() => throwOnError([{status: 200}, {status: 400}, {status: 302}])).toThrow()
56 | });
57 | });
58 |
59 | describe('convertBody', () => {
60 | it('should not convert empty responses', () => {
61 | expect(convertBody([])).toEqual([])
62 | });
63 |
64 | it('should not convert empty body', () => {
65 | expect(convertBody([{}])).toEqual([{}])
66 | });
67 |
68 | it('should not convert non-json body', () => {
69 | expect(convertBody([
70 | {body: 'foobar', contentType: 'text/plain'}
71 | ])).toEqual([
72 | {body: 'foobar', contentType: 'text/plain'}
73 | ])
74 | });
75 |
76 | it('should convert json body', () => {
77 | expect(convertBody([
78 | {body: '{"foo": "bar"}', contentType: 'application/json'}
79 | ])).toEqual([
80 | {body: {'foo': 'bar'}, contentType: 'application/json'}
81 | ])
82 | });
83 | });
84 |
--------------------------------------------------------------------------------
/minbox-logging-admin-ui/src/main/frontend/utils/rxjs.spec.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014-2019 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import {concat, EMPTY, of, throwError} from '@/utils/rxjs';
18 | import {delay, doOnSubscribe, listen} from './rxjs';
19 |
20 | describe('doOnSubscribe', () => {
21 | it('should call callback when subscribing', done => {
22 | const cb = jest.fn();
23 | EMPTY.pipe(
24 | doOnSubscribe(cb)
25 | ).subscribe({
26 | complete: () => {
27 | expect(cb).toHaveBeenCalledTimes(1);
28 | done();
29 | }
30 | });
31 | });
32 | });
33 |
34 | describe('listen', () => {
35 | it('should call callback with complete', done => {
36 | const cb = jest.fn();
37 | EMPTY.pipe(
38 | listen(cb)
39 | ).subscribe({
40 | complete: () => {
41 | expect(cb).toHaveBeenCalledTimes(1);
42 | expect(cb).toHaveBeenCalledWith('completed');
43 | done();
44 | }
45 | });
46 | });
47 |
48 | it('should call callback with executing and complete', done => {
49 | const cb = jest.fn();
50 | of(1).pipe(
51 | delay(10),
52 | listen(cb, 1)
53 | ).subscribe({
54 | complete: () => {
55 | expect(cb).toHaveBeenCalledTimes(2);
56 | expect(cb).toHaveBeenCalledWith('executing');
57 | expect(cb).toHaveBeenCalledWith('completed');
58 | done();
59 | }
60 | });
61 | });
62 |
63 | it('should call callback with failed', done => {
64 | const cb = jest.fn();
65 | throwError(new Error('test')).pipe(
66 | listen(cb)
67 | ).subscribe({
68 | error: () => {
69 | expect(cb).toHaveBeenCalledTimes(1);
70 | expect(cb).toHaveBeenCalledWith('failed');
71 | done();
72 | }
73 | });
74 | });
75 |
76 | it('should call callback with executing and failed', done => {
77 | const cb = jest.fn();
78 |
79 | concat(
80 | of(1).pipe(delay(10)),
81 | throwError(new Error('test'))
82 | ).pipe(
83 | listen(cb, 1)
84 | ).subscribe({
85 | error: () => {
86 | expect(cb).toHaveBeenCalledTimes(2);
87 | expect(cb).toHaveBeenCalledWith('executing');
88 | expect(cb).toHaveBeenCalledWith('failed');
89 | done();
90 | }
91 | });
92 | });
93 |
94 | });
95 |
--------------------------------------------------------------------------------
/minbox-logging-admin-ui/src/main/frontend/services/notification-filter.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014-2019 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import sbaConfig from '@/sba-config'
18 | import axios from '@/utils/axios';
19 | import uri from '@/utils/uri';
20 | import moment from 'moment';
21 |
22 | class NotificationFilter {
23 | constructor({expiry, ...filter}) {
24 | Object.assign(this, filter);
25 | this.expiry = expiry ? moment(expiry) : null;
26 | }
27 |
28 | affects(obj) {
29 | if (!obj) {
30 | return false;
31 | }
32 |
33 | if (this.isApplicationFilter) {
34 | return this.applicationName === obj.name;
35 | }
36 |
37 | if (this.isInstanceFilter) {
38 | return this.instanceId === obj.id;
39 | }
40 |
41 | return false;
42 | }
43 |
44 | get isApplicationFilter() {
45 | return this.hasOwnProperty('applicationName');
46 | }
47 |
48 | get isInstanceFilter() {
49 | return this.hasOwnProperty('instanceId');
50 | }
51 |
52 | async delete() {
53 | return axios.delete(uri`notifications/filters/${this.id}`);
54 | }
55 |
56 | static isSupported() {
57 | return Boolean(sbaConfig.uiSettings.notificationFilterEnabled);
58 | }
59 |
60 | static async getFilters() {
61 | return axios.get('notifications/filters', {
62 | transformResponse: NotificationFilter._transformResponse
63 | });
64 | }
65 |
66 | static async addFilter(object, ttl) {
67 | const params = {ttl};
68 | if (object.hasOwnProperty('name')) {
69 | params.applicationName = object.name;
70 | } else if (object.hasOwnProperty('id')) {
71 | params.instanceId = object.id;
72 | }
73 | return axios.post('notifications/filters', null, {
74 | params,
75 | transformResponse: NotificationFilter._transformResponse
76 | });
77 | }
78 |
79 | static _transformResponse(data) {
80 | if (!data) {
81 | return data;
82 | }
83 | const json = JSON.parse(data);
84 | if (json instanceof Array) {
85 | return json.map(NotificationFilter._toNotificationFilters).filter(f => !f.expired);
86 | }
87 | return NotificationFilter._toNotificationFilters(json);
88 | }
89 |
90 | static _toNotificationFilters(notificationFilter) {
91 | return new NotificationFilter(notificationFilter);
92 | }
93 |
94 | }
95 |
96 | export default NotificationFilter;
97 |
98 |
--------------------------------------------------------------------------------
/minbox-logging-admin-ui/src/main/frontend/utils/collections.spec.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014-2019 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 |
18 | import {anyValueMatches} from './collections';
19 |
20 | describe('anyValueMatches', () => {
21 | it('should return predicate value', () => {
22 | const predicate = jest.fn(() => true);
23 | expect(anyValueMatches('test', predicate)).toBe(true);
24 | });
25 |
26 | it('should call predicate for string', () => {
27 | const predicate = jest.fn();
28 | anyValueMatches('test', predicate);
29 | expect(predicate).toHaveBeenCalledWith('test');
30 | });
31 |
32 | it('should call predicate for number', () => {
33 | const predicate = jest.fn();
34 | anyValueMatches(1, predicate);
35 | expect(predicate).toHaveBeenCalledWith(1);
36 | });
37 |
38 | it('should call predicate for boolean', () => {
39 | const predicate = jest.fn();
40 | anyValueMatches(true, predicate);
41 | expect(predicate).toHaveBeenCalledWith(true);
42 | });
43 |
44 | it('should call predicate for null', () => {
45 | const predicate = jest.fn();
46 | anyValueMatches(null, predicate);
47 | expect(predicate).toHaveBeenCalledWith(null);
48 | });
49 |
50 | it('should call predicate for undefined', () => {
51 | const predicate = jest.fn();
52 | anyValueMatches(undefined, predicate);
53 | expect(predicate).toHaveBeenCalledWith(undefined);
54 | });
55 |
56 | it('should not call predicate for empty object', () => {
57 | const predicate = jest.fn();
58 | anyValueMatches({}, predicate);
59 | expect(predicate).not.toHaveBeenCalled()
60 | });
61 |
62 | it('should not call predicate for empty array', () => {
63 | const predicate = jest.fn();
64 | anyValueMatches([], predicate);
65 | expect(predicate).not.toHaveBeenCalled()
66 | });
67 |
68 | it('should not call predicate for elements in array', () => {
69 | const predicate = jest.fn();
70 | anyValueMatches(['test', 1, true, {value: 'nested-obj'}, ['nested-array'], [], {}], predicate);
71 | expect(predicate).toHaveBeenNthCalledWith(1, 'test');
72 | expect(predicate).toHaveBeenNthCalledWith(2, 1);
73 | expect(predicate).toHaveBeenNthCalledWith(3, true);
74 | expect(predicate).toHaveBeenNthCalledWith(4, 'nested-obj');
75 | expect(predicate).toHaveBeenNthCalledWith(5, 'nested-array');
76 | });
77 | });
78 |
--------------------------------------------------------------------------------
/minbox-logging-client/src/main/java/org/minbox/framework/logging/client/global/support/GlobalLoggingMemoryStorage.java:
--------------------------------------------------------------------------------
1 | package org.minbox.framework.logging.client.global.support;
2 |
3 | import org.minbox.framework.logging.client.global.AbstractGlobalLogging;
4 | import org.minbox.framework.logging.client.global.GlobalLoggingThreadLocal;
5 | import org.minbox.framework.logging.core.GlobalLog;
6 | import org.minbox.framework.logging.core.GlobalLogLevel;
7 | import org.minbox.framework.util.StackTraceUtil;
8 | import org.springframework.util.ObjectUtils;
9 |
10 | /**
11 | * Global log memory mode storage implementation
12 | *
13 | * @author 恒宇少年
14 | */
15 | public class GlobalLoggingMemoryStorage extends AbstractGlobalLogging {
16 | /**
17 | * collection debug level log
18 | *
19 | * @param msg log content
20 | */
21 | @Override
22 | public void debug(String msg) {
23 | GlobalLog globalLog = buildGlobalLog(GlobalLogLevel.debug, msg);
24 | GlobalLoggingThreadLocal.addGlobalLogs(globalLog);
25 | }
26 |
27 | /**
28 | * collection debug level log
29 | * for example:
30 | * this is test log,value is {}
31 | *
32 | * @param format Unformatted log content
33 | * @param arguments List of parameters corresponding to log content
34 | */
35 | @Override
36 | public void debug(String format, Object... arguments) {
37 | String log = replacePlaceholder(format, arguments);
38 | GlobalLog globalLog = buildGlobalLog(GlobalLogLevel.debug, log);
39 | GlobalLoggingThreadLocal.addGlobalLogs(globalLog);
40 | }
41 |
42 | @Override
43 | public void info(String msg) {
44 | GlobalLog globalLog = buildGlobalLog(GlobalLogLevel.info, msg);
45 | GlobalLoggingThreadLocal.addGlobalLogs(globalLog);
46 | }
47 |
48 | @Override
49 | public void info(String format, Object... arguments) {
50 | String log = replacePlaceholder(format, arguments);
51 | GlobalLog globalLog = buildGlobalLog(GlobalLogLevel.info, log);
52 | GlobalLoggingThreadLocal.addGlobalLogs(globalLog);
53 | }
54 |
55 | @Override
56 | public void error(String msg) {
57 | this.error(msg, java.util.Optional.ofNullable(null));
58 | }
59 |
60 | @Override
61 | public void error(String msg, Throwable throwable) {
62 | GlobalLog globalLog = buildGlobalLog(GlobalLogLevel.error, msg);
63 | if (!ObjectUtils.isEmpty(throwable)) {
64 | String exceptionStack = StackTraceUtil.getStackTrace(throwable);
65 | globalLog.setExceptionStack(exceptionStack);
66 | }
67 | GlobalLoggingThreadLocal.addGlobalLogs(globalLog);
68 | }
69 |
70 | @Override
71 | public void error(String format, Object... arguments) {
72 | String log = replacePlaceholder(format, arguments);
73 | GlobalLog globalLog = buildGlobalLog(GlobalLogLevel.error, log);
74 | GlobalLoggingThreadLocal.addGlobalLogs(globalLog);
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/minbox-logging-admin-ui/src/main/java/org/minbox/framework/logging/admin/ui/HomepageForwardingFilter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright [2019] [恒宇少年 - 于起宇]
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | */
17 |
18 | package org.minbox.framework.logging.admin.ui;
19 |
20 | import org.slf4j.Logger;
21 | import org.slf4j.LoggerFactory;
22 | import org.springframework.http.HttpHeaders;
23 | import org.springframework.http.MediaType;
24 | import org.springframework.web.util.UrlPathHelper;
25 |
26 | import javax.servlet.*;
27 | import javax.servlet.http.HttpServletRequest;
28 | import java.io.IOException;
29 | import java.util.List;
30 |
31 | /**
32 | * Home Page Forwarding Filter
33 | *
34 | * @author:恒宇少年 - 于起宇
35 | *
36 | * DateTime:2019-07-31 15:54
37 | * Blog:http://blog.yuqiyu.com
38 | * WebSite:http://www.jianshu.com/u/092df3f77bca
39 | * Gitee:https://gitee.com/hengboy
40 | * GitHub:https://github.com/hengboy
41 | */
42 | public class HomepageForwardingFilter implements Filter {
43 | private static final Logger log = LoggerFactory.getLogger(HomepageForwardingFilter.class);
44 | private final String homepage;
45 | private final HomepageForwardingMatcher matcher;
46 |
47 |
48 | public HomepageForwardingFilter(String homepage, List routes) {
49 | this.homepage = homepage;
50 | UrlPathHelper urlPathHelper = new UrlPathHelper();
51 | this.matcher = new HomepageForwardingMatcher<>(
52 | routes,
53 | HttpServletRequest::getMethod,
54 | urlPathHelper::getPathWithinApplication,
55 | r -> MediaType.parseMediaTypes(r.getHeader(HttpHeaders.ACCEPT))
56 | );
57 | }
58 |
59 | @Override
60 | public void doFilter(ServletRequest request,
61 | ServletResponse response,
62 | FilterChain chain) throws IOException, ServletException {
63 | if (request instanceof HttpServletRequest) {
64 | HttpServletRequest httpRequest = (HttpServletRequest) request;
65 | if (this.matcher.test(httpRequest)) {
66 | log.trace("Forwarding request with URL {} to index", httpRequest.getRequestURI());
67 | request.getRequestDispatcher(this.homepage).forward(request, response);
68 | return;
69 | }
70 | }
71 |
72 | chain.doFilter(request, response);
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/minbox-logging-admin-ui/src/main/java/org/minbox/framework/logging/admin/ui/HomepageForwardingMatcher.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright [2019] [恒宇少年 - 于起宇]
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | */
17 |
18 | package org.minbox.framework.logging.admin.ui;
19 |
20 | import org.springframework.http.HttpMethod;
21 | import org.springframework.http.MediaType;
22 |
23 | import java.util.List;
24 | import java.util.function.Function;
25 | import java.util.function.Predicate;
26 | import java.util.regex.Pattern;
27 | import java.util.stream.Collectors;
28 |
29 | /**
30 | * ApiBoot Logging Admin Ui Page Forwarding Matcher
31 | *
32 | * @author:恒宇少年 - 于起宇
33 | *
34 | * DateTime:2019-07-31 15:55
35 | * Blog:http://blog.yuqiyu.com
36 | * WebSite:http://www.jianshu.com/u/092df3f77bca
37 | * Gitee:https://gitee.com/hengboy
38 | * GitHub:https://github.com/hengboy
39 | */
40 | public class HomepageForwardingMatcher implements Predicate {
41 | private final List routes;
42 | private final Function methodAccessor;
43 | private final Function pathAccessor;
44 | private final Function> acceptsAccessor;
45 |
46 | public HomepageForwardingMatcher(List routes,
47 | Function methodAccessor,
48 | Function pathAccessor,
49 | Function> acceptsAccessor) {
50 | this.routes = toPatterns(routes);
51 | this.methodAccessor = methodAccessor;
52 | this.pathAccessor = pathAccessor;
53 | this.acceptsAccessor = acceptsAccessor;
54 | }
55 |
56 | public boolean test(T request) {
57 | if (!HttpMethod.GET.matches(this.methodAccessor.apply(request))) {
58 | return false;
59 | }
60 |
61 | if (this.routes.stream().noneMatch(p -> p.matcher(this.pathAccessor.apply(request)).matches())) {
62 | return false;
63 | }
64 |
65 | return this.acceptsAccessor.apply(request).stream().anyMatch(t -> t.includes(MediaType.TEXT_HTML));
66 | }
67 |
68 | private List toPatterns(List routes) {
69 | return routes.stream()
70 | .map(r -> "^" + r.replaceAll("/[*][*]", "(/.*)?") + "$")
71 | .map(Pattern::compile)
72 | .collect(Collectors.toList());
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/minbox-logging-client/src/main/java/org/minbox/framework/logging/client/admin/discovery/lb/support/SmoothWeightedRoundRobinStrategy.java:
--------------------------------------------------------------------------------
1 | package org.minbox.framework.logging.client.admin.discovery.lb.support;
2 |
3 | import org.minbox.framework.logging.client.MinBoxLoggingException;
4 | import org.minbox.framework.logging.client.admin.discovery.lb.LoadBalanceNode;
5 |
6 | import java.util.Iterator;
7 | import java.util.List;
8 | import java.util.concurrent.ConcurrentHashMap;
9 | import java.util.concurrent.ConcurrentMap;
10 | import java.util.concurrent.locks.ReentrantLock;
11 |
12 | /**
13 | * The {@link org.minbox.framework.logging.client.admin.discovery.lb.LoadBalanceStrategy} Poll strategy
14 | *
15 | * @author 恒宇少年
16 | * @see DefaultLoadBalanceStrategy
17 | * @see org.minbox.framework.logging.client.admin.discovery.lb.LoadBalanceStrategy
18 | */
19 | public class SmoothWeightedRoundRobinStrategy extends DefaultLoadBalanceStrategy {
20 | /**
21 | * load balance node {@link LoadBalanceNode}
22 | */
23 | private ConcurrentMap nodes = new ConcurrentHashMap();
24 |
25 | private ReentrantLock lock = new ReentrantLock();
26 |
27 | /**
28 | * lookup load-balanced logging admin address {@link LoadBalanceNode#getAddress()}
29 | * lock admin address by {@link ReentrantLock}
30 | *
31 | * @param adminAddress logging admin address array
32 | * @return load-balanced logging admin address
33 | * @throws MinBoxLoggingException MinBox Logging Exception
34 | */
35 | @Override
36 | public String lookup(String[] adminAddress) throws MinBoxLoggingException {
37 | List loadBalanceNodeList = initNodeList(adminAddress);
38 | loadBalanceNodeList.stream().forEach(loadBalanceNode -> nodes.put(loadBalanceNode.getAddress(), loadBalanceNode));
39 | try {
40 | lock.lock();
41 | return this.findMatchAddress();
42 | } finally {
43 | lock.unlock();
44 | }
45 | }
46 |
47 | /**
48 | * Find match logging admin address {@link LoadBalanceNode#getAddress()}
49 | * Obtaining the Node with the Largest Weight
50 | *
51 | * @return load-balanced logging admin address
52 | */
53 | private String findMatchAddress() {
54 | int totalWeight = 0;
55 | LoadBalanceNode maxNode = null;
56 | int maxWeight = 0;
57 | Iterator iterator = nodes.keySet().iterator();
58 | while (iterator.hasNext()) {
59 | LoadBalanceNode n = nodes.get(iterator.next());
60 | totalWeight += n.getInitWeight();
61 | n.setCurrentWeight(n.getCurrentWeight() + n.getInitWeight());
62 | if (maxNode == null || maxWeight < n.getCurrentWeight()) {
63 | maxNode = n;
64 | maxWeight = n.getCurrentWeight();
65 | }
66 | }
67 | maxNode.setCurrentWeight(maxNode.getCurrentWeight() - totalWeight);
68 | return maxNode.getAddress();
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/minbox-logging-samples/logging-client-sample/src/main/java/org/minbox/framework/logging/client/sample/LoggingClientConfiguration.java:
--------------------------------------------------------------------------------
1 | package org.minbox.framework.logging.client.sample;
2 |
3 | import org.minbox.framework.logging.client.LoggingFactoryBean;
4 | import org.minbox.framework.logging.client.admin.discovery.support.LoggingAppointAdminDiscovery;
5 | import org.minbox.framework.logging.client.global.GlobalLogging;
6 | import org.minbox.framework.logging.client.global.support.GlobalLoggingMemoryStorage;
7 | import org.minbox.framework.logging.client.interceptor.web.LoggingWebInterceptor;
8 | import org.minbox.framework.logging.client.span.LogSpanIdGenerator;
9 | import org.minbox.framework.logging.client.tracer.LogTraceIdGenerator;
10 | import org.springframework.beans.factory.annotation.Autowired;
11 | import org.springframework.context.annotation.Bean;
12 | import org.springframework.context.annotation.Configuration;
13 | import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
14 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
15 |
16 | /**
17 | * Logging Client 配置
18 | *
19 | * @author 恒宇少年
20 | */
21 | @Configuration
22 | public class LoggingClientConfiguration implements WebMvcConfigurer {
23 | /**
24 | * Logging Client提供的日志拦截器 {@link LoggingWebInterceptor}
25 | */
26 | @Autowired
27 | private LoggingWebInterceptor loggingWebInterceptor;
28 |
29 | /**
30 | * 注册使用拦截器
31 | *
32 | * @param registry
33 | */
34 | @Override
35 | public void addInterceptors(InterceptorRegistry registry) {
36 | registry.addInterceptor(loggingWebInterceptor).addPathPatterns("/**");
37 | }
38 |
39 | /**
40 | * 初始化{@link LoggingFactoryBean}
41 | *
42 | * @return {@link LoggingFactoryBean}
43 | */
44 | @Bean
45 | public LoggingFactoryBean loggingFactoryBean() {
46 | LoggingFactoryBean factoryBean = new LoggingFactoryBean();
47 | // 设置自定义生成traceId
48 | factoryBean.setTraceGenerator(customerTraceGenerator());
49 | // 设置自定义生成spanId
50 | factoryBean.setSpanGenerator(customerSpanGenerator());
51 | // 设置在控制台输出日志
52 | factoryBean.setShowConsoleLog(true);
53 | // 格式化控制台输出的日志
54 | factoryBean.setFormatConsoleLog(true);
55 | factoryBean.setLoggingAdminDiscovery(
56 | new LoggingAppointAdminDiscovery(new String[]{"user:123456@localhost:9091"})
57 | );
58 | return factoryBean;
59 | }
60 |
61 | /**
62 | * 自定义生成traceId
63 | *
64 | * @return {@link LogTraceIdGenerator}
65 | */
66 | @Bean
67 | public LogTraceIdGenerator customerTraceGenerator() {
68 | return new CustomerTraceIdGenerator();
69 | }
70 |
71 | /**
72 | * 自定义生成spanId
73 | *
74 | * @return
75 | */
76 | @Bean
77 | public LogSpanIdGenerator customerSpanGenerator() {
78 | return new CustomerSpanIdGenerator();
79 | }
80 |
81 | @Bean
82 | public GlobalLogging globalLogging() {
83 | return new GlobalLoggingMemoryStorage();
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/minbox-logging-admin-ui/src/main/frontend/services/application.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014-2019 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import axios, {redirectOn401} from '@/utils/axios';
18 | import waitForPolyfill from '@/utils/eventsource-polyfill';
19 | import {concat, from, ignoreElements, Observable} from '@/utils/rxjs';
20 | import uri from '@/utils/uri';
21 | import sortBy from 'lodash/sortBy';
22 | import Instance from './instance';
23 |
24 | const actuatorMimeTypes = [
25 | 'application/vnd.spring-boot.actuator.v2+json',
26 | 'application/vnd.spring-boot.actuator.v1+json',
27 | 'application/json'
28 | ];
29 |
30 | export const hasMatchingContentType = (contentType, compatibleContentTypes) =>
31 | Boolean(contentType) && compatibleContentTypes.includes(contentType.replace(/;.*$/, ''));
32 |
33 | export const throwOnError = (responses) => responses.forEach(r => {
34 | if (r.status >= 400) {
35 | const error = new Error(`Request for Instance '${r.instanceId}' failed with status ${r.status}`);
36 | error.responses = responses;
37 | throw error
38 | }
39 | });
40 |
41 | export const convertBody = (responses) => responses.map(res => {
42 | if (res.body && hasMatchingContentType(res.contentType, actuatorMimeTypes)) {
43 | return {
44 | ...res,
45 | body: JSON.parse(res.body)
46 | }
47 | }
48 | return res;
49 | });
50 |
51 | class Application {
52 | constructor({name, instances, ...application}) {
53 | Object.assign(this, application);
54 | this.name = name;
55 | this.axios = axios.create({
56 | baseURL: uri`applications/${this.name}/`,
57 | });
58 | this.axios.interceptors.response.use(response => response, redirectOn401()
59 | );
60 | this.instances = sortBy(instances.map(i => new Instance(i), [instance => instance.registration.healthUrl]));
61 | }
62 |
63 | filterInstances(predicate) {
64 | return new Application({
65 | ...this,
66 | instances: this.instances.filter(predicate)
67 | })
68 | }
69 |
70 | findInstance(instanceId) {
71 | return this.instances.find(instance => instance.id === instanceId);
72 | }
73 |
74 | get isUnregisterable() {
75 | return this.instances.findIndex(i => i.isUnregisterable) >= 0;
76 | }
77 |
78 | async unregister() {
79 | return this.axios.delete('', {
80 | headers: {'Accept': 'application/json'}
81 | })
82 | }
83 |
84 |
85 | static _transformResponse(data) {
86 | if (!data) {
87 | return data;
88 | }
89 | const json = JSON.parse(data);
90 | if (json instanceof Array) {
91 | const applications = json.map(j => new Application(j));
92 | return sortBy(applications, [item => item.name]);
93 | }
94 | return new Application(json);
95 | }
96 | }
97 |
98 | export default Application;
99 |
--------------------------------------------------------------------------------
/minbox-logging-client/src/main/java/org/minbox/framework/logging/client/filter/LoggingBodyFilter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright [2019] [恒宇少年 - 于起宇]
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | */
17 |
18 | package org.minbox.framework.logging.client.filter;
19 |
20 | import org.minbox.framework.logging.client.LoggingFactoryBean;
21 | import org.minbox.framework.util.UrlUtils;
22 | import org.minbox.framework.web.request.RequestWrapper;
23 | import org.minbox.framework.web.response.ResponseWrapper;
24 | import org.minbox.framework.web.util.HttpRequestUtil;
25 |
26 | import javax.servlet.*;
27 | import javax.servlet.annotation.WebFilter;
28 | import javax.servlet.http.HttpServletRequest;
29 | import javax.servlet.http.HttpServletResponse;
30 | import java.io.IOException;
31 |
32 | /**
33 | * ApiBoot Logging Body(Request / Response) Filter
34 | * Encapsulation principal obtains the corresponding replicated content
35 | *
36 | * @author 恒宇少年
37 | */
38 | @WebFilter(urlPatterns = "/*", filterName = "loggingBodyFilter")
39 | public class LoggingBodyFilter implements Filter {
40 | /**
41 | * the bean name of {@link LoggingBodyFilter}
42 | */
43 | public static final String BEAN_NAME = "loggingBodyFilter";
44 | /**
45 | * {@link LoggingFactoryBean}
46 | */
47 | private LoggingFactoryBean factoryBean;
48 |
49 | public LoggingBodyFilter(LoggingFactoryBean factoryBean) {
50 | this.factoryBean = factoryBean;
51 | }
52 |
53 | /**
54 | * Wrapper Body
55 | * replace http request body instance
56 | * replace http response body instance
57 | *
58 | * @param request http request
59 | * @param response http response
60 | * @param filterChain filter chain
61 | * @throws IOException ioException
62 | * @throws ServletException servlet Exception
63 | */
64 | @Override
65 | public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
66 | // see https://github.com/minbox-projects/api-boot/issues/85
67 | HttpServletRequest servletRequest = (HttpServletRequest) request;
68 | String uri = HttpRequestUtil.getUri(servletRequest);
69 | // see https://gitee.com/minbox-projects/minbox-logging/issues/I1JWSK
70 | if (!HttpRequestUtil.isMultipart(request) && !UrlUtils.isIgnore(factoryBean.getIgnorePaths(), uri)) {
71 | RequestWrapper requestWrapper = new RequestWrapper(servletRequest);
72 | ResponseWrapper responseWrapper = new ResponseWrapper((HttpServletResponse) response);
73 | filterChain.doFilter(requestWrapper, responseWrapper);
74 | responseWrapper.flushBuffer();
75 | } else {
76 | filterChain.doFilter(request, response);
77 | }
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/minbox-logging-admin-ui/src/main/frontend/store.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014-2019 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | import Application from '@/services/application';
17 | import {bufferTime, concat, concatMap, defer, delay, filter, map, retryWhen, tap} from '@/utils/rxjs';
18 |
19 | export default class {
20 | constructor() {
21 | this._listeners = {};
22 | this._applications = new Map();
23 | this.applications = [];
24 | this.applications.findInstance = (instanceId) => {
25 | for (let application of this.applications) {
26 | const instance = application.findInstance(instanceId);
27 | if (instance) {
28 | return instance;
29 | }
30 | }
31 | return undefined;
32 | };
33 | this.applications.findApplicationForInstance = (instanceId) => {
34 | return this.applications.find(application => Boolean(application.findInstance(instanceId)));
35 | };
36 | }
37 |
38 | addEventListener(type, listener) {
39 | if (!(type in this._listeners)) {
40 | this._listeners[type] = [];
41 | }
42 | this._listeners[type].push(listener);
43 | }
44 |
45 | removeEventListener(type, listener) {
46 | if (!(type in this._listeners)) {
47 | return;
48 | }
49 |
50 | const idx = this._listeners[type].indexOf(listener);
51 | if (idx > 0) {
52 | this._listeners[type].splice(idx, 1);
53 | }
54 | }
55 |
56 | _dispatchEvent(type, ...args) {
57 | if (!(type in this._listeners)) {
58 | return;
59 | }
60 | const target = this;
61 | this._listeners[type].forEach(
62 | listener => listener.call(target, ...args)
63 | )
64 | }
65 |
66 | start() {
67 |
68 | }
69 |
70 | updateApplications(applications) {
71 | applications.forEach(a => this.updateApplication(a));
72 | this.applications.splice(0, this.applications.length, ...Array.from(this._applications.values()));
73 | }
74 |
75 | updateApplication(application) {
76 | const oldApplication = this._applications.get(application.name);
77 | if (!oldApplication && application.instances.length > 0) {
78 | this._applications.set(application.name, application);
79 | this._dispatchEvent('added', application);
80 | } else if (oldApplication && application.instances.length > 0) {
81 | this._applications.set(application.name, application);
82 | this._dispatchEvent('updated', application, oldApplication);
83 | } else if (oldApplication && application.instances.length <= 0) {
84 | this._applications.delete(application.name);
85 | this._dispatchEvent('removed', oldApplication);
86 | }
87 | }
88 |
89 | stop() {
90 | if (this.subscription) {
91 | try {
92 | !this.subscription.closed && this.subscription.unsubscribe();
93 | } finally {
94 | this.subscription = null;
95 | }
96 | }
97 | }
98 | }
99 |
--------------------------------------------------------------------------------