├── .github
└── workflows
│ └── maven.yml
├── LICENSE
├── README.md
├── maple-airlift
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── io
│ │ │ └── soabase
│ │ │ └── maple
│ │ │ └── airlift
│ │ │ ├── AirliftLogger.java
│ │ │ ├── MapleAirliftSpi.java
│ │ │ ├── MapleFactory.java
│ │ │ ├── MapleLogger.java
│ │ │ ├── MapleLoggerImpl.java
│ │ │ └── Utils.java
│ └── resources
│ │ └── META-INF
│ │ └── services
│ │ └── io.soabase.maple.spi.MapleSpi
│ └── test
│ └── java
│ └── io
│ └── soabase
│ └── maple
│ └── airlift
│ ├── Schema.java
│ ├── TestLogger.java
│ └── TestLogging.java
├── maple-benchmarks
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── io
│ │ └── soabase
│ │ └── maple
│ │ └── benchmarks
│ │ ├── FakeAppender.java
│ │ ├── Schema.java
│ │ ├── StandardLoggerBenchmark.java
│ │ ├── StructuredLoggerBenchmark.java
│ │ └── Utils.java
│ └── resources
│ └── logback.xml
├── maple-core
├── pom.xml
└── src
│ ├── main
│ └── java
│ │ └── io
│ │ └── soabase
│ │ └── maple
│ │ ├── api
│ │ ├── LevelLogger.java
│ │ ├── LoggingLevel.java
│ │ ├── MapleFormatter.java
│ │ ├── MapleLoggerApi.java
│ │ ├── MdcCloseable.java
│ │ ├── NameValue.java
│ │ ├── Names.java
│ │ ├── NamesValues.java
│ │ ├── Specialization.java
│ │ ├── Statement.java
│ │ ├── Values.java
│ │ ├── annotations
│ │ │ ├── DoNotLog.java
│ │ │ ├── MdcDefaultValue.java
│ │ │ ├── Required.java
│ │ │ └── SortOrder.java
│ │ └── exceptions
│ │ │ ├── InvalidSchemaException.java
│ │ │ └── MissingSchemaValueException.java
│ │ ├── core
│ │ ├── GeneratedMetaInstance.java
│ │ ├── Generator.java
│ │ ├── Instance.java
│ │ ├── InstanceFactory.java
│ │ ├── Key.java
│ │ ├── MapleLoggerBase.java
│ │ ├── NamesValuesImp.java
│ │ ├── SpecializedNamesValues.java
│ │ └── StandardMapleLogger.java
│ │ ├── formatters
│ │ ├── ModelFormatter.java
│ │ └── StandardFormatter.java
│ │ └── spi
│ │ ├── Loader.java
│ │ ├── Loaders.java
│ │ ├── MapleSpi.java
│ │ ├── MetaInstance.java
│ │ ├── StandardMapleSpi.java
│ │ └── StandardNamesBuilder.java
│ └── test
│ └── java
│ └── io
│ └── soabase
│ └── maple
│ ├── Address.java
│ ├── LogEvent.java
│ ├── MockMapleLogger.java
│ ├── TestFormatters.java
│ ├── TestGeneration.java
│ ├── TestLogging.java
│ └── schema
│ ├── BasicSchema.java
│ ├── HasMdcDefault.java
│ ├── HasRequired.java
│ ├── HasSortOrder.java
│ ├── MultiMethodDefaults.java
│ ├── Schema.java
│ └── invalid
│ ├── BadReturnType.java
│ ├── CannotBeAClass.java
│ ├── Duplicates.java
│ ├── InvalidMethod.java
│ ├── MustReturnRightTypeInheritance.java
│ └── MustTake1ArgumentB.java
├── maple-examples
├── README.md
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── com
│ │ └── myco
│ │ └── app
│ │ ├── logging
│ │ ├── Logging.java
│ │ ├── LoggingEventType.java
│ │ └── LoggingSchema.java
│ │ ├── mdc
│ │ ├── MdcSchema.java
│ │ ├── Request.java
│ │ ├── RequestHandler.java
│ │ ├── RestEndpoint.java
│ │ └── TransactionMetaData.java
│ │ └── request
│ │ ├── PayloadModel.java
│ │ ├── RequestHandler.java
│ │ └── UpdateService.java
│ └── resources
│ └── logback.xml
├── maple-slf4j
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── io
│ │ │ └── soabase
│ │ │ └── maple
│ │ │ └── slf4j
│ │ │ ├── MapleFactory.java
│ │ │ ├── MapleLogger.java
│ │ │ ├── MapleLoggerImpl.java
│ │ │ ├── MapleSlf4jSpi.java
│ │ │ └── Utils.java
│ └── resources
│ │ └── META-INF
│ │ └── services
│ │ └── io.soabase.maple.spi.MapleSpi
│ └── test
│ └── java
│ ├── io
│ └── soabase
│ │ └── maple
│ │ └── slf4j
│ │ ├── Schema.java
│ │ ├── SchemaWithMdc.java
│ │ └── TestLogging.java
│ └── org
│ └── slf4j
│ └── impl
│ ├── StaticLoggerBinder.java
│ └── StaticMDCBinder.java
├── pom.xml
└── src
└── etc
└── header.txt
/.github/workflows/maven.yml:
--------------------------------------------------------------------------------
1 | # This workflow will build a Java project with Maven
2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven
3 |
4 | name: Java CI with Maven
5 |
6 | on:
7 | push:
8 | branches: [ master ]
9 | pull_request:
10 | branches: [ master ]
11 |
12 | jobs:
13 | build:
14 |
15 | runs-on: ubuntu-latest
16 |
17 | steps:
18 | - uses: actions/checkout@v2
19 | - name: Set up JDK 1.8
20 | uses: actions/setup-java@v1
21 | with:
22 | java-version: 1.8
23 | - name: Build with Maven
24 | run: mvn -B package --file pom.xml
25 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 |
2 | Apache License
3 | Version 2.0, January 2004
4 | http://www.apache.org/licenses/
5 |
6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7 |
8 | 1. Definitions.
9 |
10 | "License" shall mean the terms and conditions for use, reproduction,
11 | and distribution as defined by Sections 1 through 9 of this document.
12 |
13 | "Licensor" shall mean the copyright owner or entity authorized by
14 | the copyright owner that is granting the License.
15 |
16 | "Legal Entity" shall mean the union of the acting entity and all
17 | other entities that control, are controlled by, or are under common
18 | control with that entity. For the purposes of this definition,
19 | "control" means (i) the power, direct or indirect, to cause the
20 | direction or management of such entity, whether by contract or
21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
22 | outstanding shares, or (iii) beneficial ownership of such entity.
23 |
24 | "You" (or "Your") shall mean an individual or Legal Entity
25 | exercising permissions granted by this License.
26 |
27 | "Source" form shall mean the preferred form for making modifications,
28 | including but not limited to software source code, documentation
29 | source, and configuration files.
30 |
31 | "Object" form shall mean any form resulting from mechanical
32 | transformation or translation of a Source form, including but
33 | not limited to compiled object code, generated documentation,
34 | and conversions to other media types.
35 |
36 | "Work" shall mean the work of authorship, whether in Source or
37 | Object form, made available under the License, as indicated by a
38 | copyright notice that is included in or attached to the work
39 | (an example is provided in the Appendix below).
40 |
41 | "Derivative Works" shall mean any work, whether in Source or Object
42 | form, that is based on (or derived from) the Work and for which the
43 | editorial revisions, annotations, elaborations, or other modifications
44 | represent, as a whole, an original work of authorship. For the purposes
45 | of this License, Derivative Works shall not include works that remain
46 | separable from, or merely link (or bind by name) to the interfaces of,
47 | the Work and Derivative Works thereof.
48 |
49 | "Contribution" shall mean any work of authorship, including
50 | the original version of the Work and any modifications or additions
51 | to that Work or Derivative Works thereof, that is intentionally
52 | submitted to Licensor for inclusion in the Work by the copyright owner
53 | or by an individual or Legal Entity authorized to submit on behalf of
54 | the copyright owner. For the purposes of this definition, "submitted"
55 | means any form of electronic, verbal, or written communication sent
56 | to the Licensor or its representatives, including but not limited to
57 | communication on electronic mailing lists, source code control systems,
58 | and issue tracking systems that are managed by, or on behalf of, the
59 | Licensor for the purpose of discussing and improving the Work, but
60 | excluding communication that is conspicuously marked or otherwise
61 | designated in writing by the copyright owner as "Not a Contribution."
62 |
63 | "Contributor" shall mean Licensor and any individual or Legal Entity
64 | on behalf of whom a Contribution has been received by Licensor and
65 | subsequently incorporated within the Work.
66 |
67 | 2. Grant of Copyright License. Subject to the terms and conditions of
68 | this License, each Contributor hereby grants to You a perpetual,
69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70 | copyright license to reproduce, prepare Derivative Works of,
71 | publicly display, publicly perform, sublicense, and distribute the
72 | Work and such Derivative Works in Source or Object form.
73 |
74 | 3. Grant of Patent License. Subject to the terms and conditions of
75 | this License, each Contributor hereby grants to You a perpetual,
76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77 | (except as stated in this section) patent license to make, have made,
78 | use, offer to sell, sell, import, and otherwise transfer the Work,
79 | where such license applies only to those patent claims licensable
80 | by such Contributor that are necessarily infringed by their
81 | Contribution(s) alone or by combination of their Contribution(s)
82 | with the Work to which such Contribution(s) was submitted. If You
83 | institute patent litigation against any entity (including a
84 | cross-claim or counterclaim in a lawsuit) alleging that the Work
85 | or a Contribution incorporated within the Work constitutes direct
86 | or contributory patent infringement, then any patent licenses
87 | granted to You under this License for that Work shall terminate
88 | as of the date such litigation is filed.
89 |
90 | 4. Redistribution. You may reproduce and distribute copies of the
91 | Work or Derivative Works thereof in any medium, with or without
92 | modifications, and in Source or Object form, provided that You
93 | meet the following conditions:
94 |
95 | (a) You must give any other recipients of the Work or
96 | Derivative Works a copy of this License; and
97 |
98 | (b) You must cause any modified files to carry prominent notices
99 | stating that You changed the files; and
100 |
101 | (c) You must retain, in the Source form of any Derivative Works
102 | that You distribute, all copyright, patent, trademark, and
103 | attribution notices from the Source form of the Work,
104 | excluding those notices that do not pertain to any part of
105 | the Derivative Works; and
106 |
107 | (d) If the Work includes a "NOTICE" text file as part of its
108 | distribution, then any Derivative Works that You distribute must
109 | include a readable copy of the attribution notices contained
110 | within such NOTICE file, excluding those notices that do not
111 | pertain to any part of the Derivative Works, in at least one
112 | of the following places: within a NOTICE text file distributed
113 | as part of the Derivative Works; within the Source form or
114 | documentation, if provided along with the Derivative Works; or,
115 | within a display generated by the Derivative Works, if and
116 | wherever such third-party notices normally appear. The contents
117 | of the NOTICE file are for informational purposes only and
118 | do not modify the License. You may add Your own attribution
119 | notices within Derivative Works that You distribute, alongside
120 | or as an addendum to the NOTICE text from the Work, provided
121 | that such additional attribution notices cannot be construed
122 | as modifying the License.
123 |
124 | You may add Your own copyright statement to Your modifications and
125 | may provide additional or different license terms and conditions
126 | for use, reproduction, or distribution of Your modifications, or
127 | for any such Derivative Works as a whole, provided Your use,
128 | reproduction, and distribution of the Work otherwise complies with
129 | the conditions stated in this License.
130 |
131 | 5. Submission of Contributions. Unless You explicitly state otherwise,
132 | any Contribution intentionally submitted for inclusion in the Work
133 | by You to the Licensor shall be under the terms and conditions of
134 | this License, without any additional terms or conditions.
135 | Notwithstanding the above, nothing herein shall supersede or modify
136 | the terms of any separate license agreement you may have executed
137 | with Licensor regarding such Contributions.
138 |
139 | 6. Trademarks. This License does not grant permission to use the trade
140 | names, trademarks, service marks, or product names of the Licensor,
141 | except as required for reasonable and customary use in describing the
142 | origin of the Work and reproducing the content of the NOTICE file.
143 |
144 | 7. Disclaimer of Warranty. Unless required by applicable law or
145 | agreed to in writing, Licensor provides the Work (and each
146 | Contributor provides its Contributions) on an "AS IS" BASIS,
147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148 | implied, including, without limitation, any warranties or conditions
149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150 | PARTICULAR PURPOSE. You are solely responsible for determining the
151 | appropriateness of using or redistributing the Work and assume any
152 | risks associated with Your exercise of permissions under this License.
153 |
154 | 8. Limitation of Liability. In no event and under no legal theory,
155 | whether in tort (including negligence), contract, or otherwise,
156 | unless required by applicable law (such as deliberate and grossly
157 | negligent acts) or agreed to in writing, shall any Contributor be
158 | liable to You for damages, including any direct, indirect, special,
159 | incidental, or consequential damages of any character arising as a
160 | result of this License or out of the use or inability to use the
161 | Work (including but not limited to damages for loss of goodwill,
162 | work stoppage, computer failure or malfunction, or any and all
163 | other commercial damages or losses), even if such Contributor
164 | has been advised of the possibility of such damages.
165 |
166 | 9. Accepting Warranty or Additional Liability. While redistributing
167 | the Work or Derivative Works thereof, You may choose to offer,
168 | and charge a fee for, acceptance of support, warranty, indemnity,
169 | or other liability obligations and/or rights consistent with this
170 | License. However, in accepting such obligations, You may act only
171 | on Your own behalf and on Your sole responsibility, not on behalf
172 | of any other Contributor, and only if You agree to indemnify,
173 | defend, and hold each Contributor harmless for any liability
174 | incurred by, or claims asserted against, such Contributor by reason
175 | of your accepting any such warranty or additional liability.
176 |
177 | END OF TERMS AND CONDITIONS
178 |
179 | APPENDIX: How to apply the Apache License to your work.
180 |
181 | To apply the Apache License to your work, attach the following
182 | boilerplate notice, with the fields enclosed by brackets "[]"
183 | replaced with your own identifying information. (Don't include
184 | the brackets!) The text should be enclosed in the appropriate
185 | comment syntax for the file format. We also recommend that a
186 | file or class name and description of purpose be included on the
187 | same "printed page" as the copyright notice for easier
188 | identification within third-party archives.
189 |
190 | Copyright [yyyy] [name of copyright owner]
191 |
192 | Licensed under the Apache License, Version 2.0 (the "License");
193 | you may not use this file except in compliance with the License.
194 | You may obtain a copy of the License at
195 |
196 | http://www.apache.org/licenses/LICENSE-2.0
197 |
198 | Unless required by applicable law or agreed to in writing, software
199 | distributed under the License is distributed on an "AS IS" BASIS,
200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201 | See the License for the specific language governing permissions and
202 | limitations under the License.
203 |
--------------------------------------------------------------------------------
/maple-airlift/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | maple-parent
5 | io.soabase.maple
6 | 3.2-SNAPSHOT
7 |
8 | 4.0.0
9 |
10 | maple-airlift
11 |
12 |
13 |
14 | io.soabase.maple
15 | maple-core
16 |
17 |
18 |
19 | io.airlift
20 | log
21 | provided
22 |
23 |
24 |
25 | io.airlift
26 | log-manager
27 | provided
28 |
29 |
30 |
31 | org.junit.jupiter
32 | junit-jupiter
33 | test
34 |
35 |
36 |
37 | org.assertj
38 | assertj-core
39 | test
40 |
41 |
42 |
--------------------------------------------------------------------------------
/maple-airlift/src/main/java/io/soabase/maple/airlift/AirliftLogger.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Jordan Zimmerman
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 | package io.soabase.maple.airlift;
17 |
18 | import io.airlift.log.Logger;
19 |
20 | public class AirliftLogger {
21 | private final Logger airliftLogger;
22 | private final java.util.logging.Logger javaLogger;
23 |
24 | public AirliftLogger(Logger airliftLogger, java.util.logging.Logger javaLogger) {
25 | this.airliftLogger = airliftLogger;
26 | this.javaLogger = javaLogger;
27 | }
28 |
29 | public void debug(Throwable exception, String message)
30 | {
31 | airliftLogger.debug(exception, message);
32 | }
33 |
34 | public void debug(String message)
35 | {
36 | airliftLogger.debug(message);
37 | }
38 |
39 | public void debug(String format, Object... args)
40 | {
41 | airliftLogger.debug(format, args);
42 | }
43 |
44 | public void debug(Throwable exception, String format, Object... args)
45 | {
46 | airliftLogger.debug(exception, format, args);
47 | }
48 |
49 | public void info(String message)
50 | {
51 | airliftLogger.info(message);
52 | }
53 |
54 | public void info(String format, Object... args)
55 | {
56 | airliftLogger.info(format, args);
57 | }
58 |
59 | public void warn(Throwable exception, String message)
60 | {
61 | airliftLogger.warn(exception, message);
62 | }
63 |
64 | public void warn(String message)
65 | {
66 | airliftLogger.warn(message);
67 | }
68 |
69 | public void warn(Throwable exception, String format, Object... args)
70 | {
71 | airliftLogger.warn(exception, format, args);
72 | }
73 |
74 | public void warn(String format, Object... args)
75 | {
76 | airliftLogger.warn(format, args);
77 | }
78 |
79 | public void error(Throwable exception, String message)
80 | {
81 | airliftLogger.error(exception, message);
82 | }
83 |
84 | public void error(String message)
85 | {
86 | airliftLogger.error(message);
87 | }
88 |
89 | public void error(Throwable exception, String format, Object... args)
90 | {
91 | airliftLogger.error(exception, format, args);
92 | }
93 |
94 | public void error(Throwable exception)
95 | {
96 | airliftLogger.error(exception);
97 | }
98 |
99 | public void error(String format, Object... args)
100 | {
101 | airliftLogger.error(format, args);
102 | }
103 |
104 | public boolean isDebugEnabled()
105 | {
106 | return airliftLogger.isDebugEnabled();
107 | }
108 |
109 | public boolean isInfoEnabled()
110 | {
111 | return airliftLogger.isInfoEnabled();
112 | }
113 |
114 | public java.util.logging.Logger getJavaLogger() {
115 | return javaLogger;
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/maple-airlift/src/main/java/io/soabase/maple/airlift/MapleAirliftSpi.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Jordan Zimmerman
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 | package io.soabase.maple.airlift;
17 |
18 | import io.soabase.maple.spi.StandardMapleSpi;
19 |
20 | public class MapleAirliftSpi extends StandardMapleSpi {
21 | @Override
22 | public Object getMdcValue(String name) {
23 | throw new UnsupportedOperationException("Airlift logging does not currently support MDC");
24 | }
25 |
26 | @Override
27 | public void putMdcValue(String name, Object value) {
28 | throw new UnsupportedOperationException("Airlift logging does not currently support MDC");
29 | }
30 |
31 | @Override
32 | public void removeMdcValue(String name) {
33 | throw new UnsupportedOperationException("Airlift logging does not currently support MDC");
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/maple-airlift/src/main/java/io/soabase/maple/airlift/MapleFactory.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Jordan Zimmerman
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 | package io.soabase.maple.airlift;
17 |
18 | import io.airlift.log.Logger;
19 | import io.soabase.maple.api.MapleFormatter;
20 | import io.soabase.maple.spi.MapleSpi;
21 | import io.soabase.maple.spi.MetaInstance;
22 |
23 | /**
24 | * Main accessor for structured logging instances
25 | */
26 | public class MapleFactory {
27 | /**
28 | * Return a structured logger by first calling {@link Logger#get(String)} and
29 | * then wrapping it in a {@link MapleLogger}
30 | *
31 | * @param name the name to use to get the logger
32 | * @param schemaClass logging schema
33 | * @return {@link MapleLogger}
34 | */
35 | public static MapleLogger getLogger(String name, Class schemaClass) {
36 | java.util.logging.Logger javaLogger = java.util.logging.Logger.getLogger(name);
37 | Logger airliftLogger = Logger.get(name);
38 | return getLogger(new AirliftLogger(airliftLogger, javaLogger), schemaClass);
39 | }
40 |
41 | /**
42 | * Return a structured logger by first calling {@link Logger#get(Class)} and
43 | * then wrapping it in a {@link MapleLogger}
44 | *
45 | * @param clazz the class to use to get the logger
46 | * @param schemaClass logging schema
47 | * @return {@link MapleLogger}
48 | */
49 | public static MapleLogger getLogger(Class> clazz, Class schemaClass) {
50 | return getLogger(clazz.getName(), schemaClass);
51 | }
52 |
53 | /**
54 | * Return a {@link MapleLogger} that wraps the given logger
55 | *
56 | * @param logger logger to wrap
57 | * @param schemaClass logging schema
58 | * @return {@link MapleLogger}
59 | */
60 | public static MapleLogger getLogger(AirliftLogger logger, Class schemaClass) {
61 | MetaInstance metaInstance = MapleSpi.instance().generate(schemaClass);
62 | return new MapleLoggerImpl<>(metaInstance, logger);
63 | }
64 |
65 | /**
66 | * Change the global production mode value. When production mode is {@code false}, schema methods
67 | * annotation with {@link io.soabase.maple.api.annotations.Required} with throw an exception
68 | * when they are {@code null}. When production mode is {@code true} this doesn't occur.
69 | *
70 | * @param newValue new production mode value
71 | */
72 | public static void setProductionMode(boolean newValue) {
73 | MapleSpi.instance().setProductionMode(newValue);
74 | }
75 |
76 | /**
77 | * Return the current value of production mode
78 | *
79 | * @return true/false
80 | */
81 | public static boolean getProductionMode() {
82 | return MapleSpi.instance().getProductionMode();
83 | }
84 |
85 | /**
86 | * Change the logging formatter in use.
87 | *
88 | * @param formatter new formatter. Pass {@code null} to use the default formatter
89 | */
90 | public static void setFormatter(MapleFormatter formatter) {
91 | MapleSpi.instance().setFormatter(formatter);
92 | }
93 |
94 | /**
95 | * Return the current logging formatter
96 | *
97 | * @return logging formatter
98 | */
99 | public static MapleFormatter getFormatter() {
100 | return MapleSpi.instance().getFormatter();
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/maple-airlift/src/main/java/io/soabase/maple/airlift/MapleLogger.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Jordan Zimmerman
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 | package io.soabase.maple.airlift;
17 |
18 | import io.soabase.maple.api.MapleLoggerApi;
19 |
20 | public interface MapleLogger extends MapleLoggerApi {
21 | /**
22 | * Return the underlying airlift logger
23 | *
24 | * @return airlift logger
25 | */
26 | AirliftLogger logger();
27 | }
28 |
--------------------------------------------------------------------------------
/maple-airlift/src/main/java/io/soabase/maple/airlift/MapleLoggerImpl.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Jordan Zimmerman
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 | package io.soabase.maple.airlift;
17 |
18 | import io.soabase.maple.core.StandardMapleLogger;
19 | import io.soabase.maple.spi.MetaInstance;
20 |
21 | class MapleLoggerImpl extends StandardMapleLogger implements MapleLogger {
22 | MapleLoggerImpl(MetaInstance metaInstance, AirliftLogger logger) {
23 | super(metaInstance, logger, Utils::isEnabledLoggerName, Utils::levelLogger);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/maple-airlift/src/main/java/io/soabase/maple/airlift/Utils.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Jordan Zimmerman
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 | package io.soabase.maple.airlift;
17 |
18 | import io.soabase.maple.api.LevelLogger;
19 | import io.soabase.maple.api.LoggingLevel;
20 |
21 | import java.util.logging.Level;
22 |
23 | class Utils {
24 | static String isEnabledLoggerName(LoggingLevel level, AirliftLogger logger) {
25 | switch (level) {
26 | case ERROR:
27 | return logger.getJavaLogger().isLoggable(Level.SEVERE) ? logger.getJavaLogger().getName() : null;
28 | case WARN:
29 | return logger.getJavaLogger().isLoggable(Level.WARNING) ? logger.getJavaLogger().getName() : null;
30 | case INFO:
31 | return logger.isInfoEnabled() ? logger.getJavaLogger().getName() : null;
32 | case DEBUG:
33 | return logger.isDebugEnabled() ? logger.getJavaLogger().getName() : null;
34 | case TRACE:
35 | return null;
36 | }
37 | throw new IllegalStateException(); // should never get here
38 | }
39 |
40 | static LevelLogger levelLogger(LoggingLevel level, AirliftLogger logger) {
41 | switch (level) {
42 | case ERROR:
43 | return (msg, t) -> error(logger, msg, t);
44 | case WARN:
45 | return (msg, t) -> warn(logger, msg, t);
46 | case INFO:
47 | return (msg, t) -> info(logger, msg, t);
48 | case DEBUG:
49 | return (msg, t) -> debug(logger, msg, t);
50 | case TRACE:
51 | return (msg, t) -> {
52 | }; // airlift doesn't support trace
53 | }
54 | throw new IllegalStateException(); // should never get here
55 | }
56 |
57 | private static void error(AirliftLogger logger, String msg, Throwable t) {
58 | if (t != null) {
59 | logger.error(t, msg);
60 | } else {
61 | logger.error(msg);
62 | }
63 | }
64 |
65 | private static void warn(AirliftLogger logger, String msg, Throwable t) {
66 | if (t != null) {
67 | logger.warn(t, msg);
68 | } else {
69 | logger.warn(msg);
70 | }
71 | }
72 |
73 | private static void info(AirliftLogger logger, String msg, Throwable t) {
74 | if (t != null) {
75 | logger.info(msg + " %s", t);
76 | } else {
77 | logger.info(msg);
78 | }
79 | }
80 |
81 | private static void debug(AirliftLogger logger, String msg, Throwable t) {
82 | if (t != null) {
83 | logger.debug(t, msg, t);
84 | } else {
85 | logger.debug(msg);
86 | }
87 | }
88 |
89 | private Utils() {
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/maple-airlift/src/main/resources/META-INF/services/io.soabase.maple.spi.MapleSpi:
--------------------------------------------------------------------------------
1 | io.soabase.maple.airlift.MapleAirliftSpi
--------------------------------------------------------------------------------
/maple-airlift/src/test/java/io/soabase/maple/airlift/Schema.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Jordan Zimmerman
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 | package io.soabase.maple.airlift;
17 |
18 | public interface Schema {
19 | Schema name(String name);
20 |
21 | Schema age(int age);
22 | }
23 |
--------------------------------------------------------------------------------
/maple-airlift/src/test/java/io/soabase/maple/airlift/TestLogger.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Jordan Zimmerman
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 | package io.soabase.maple.airlift;
17 |
18 | import java.util.ArrayList;
19 | import java.util.List;
20 | import java.util.Objects;
21 | import java.util.concurrent.CopyOnWriteArrayList;
22 | import java.util.logging.Level;
23 | import java.util.logging.Logger;
24 |
25 | class TestLogger extends Logger {
26 | private final List events = new CopyOnWriteArrayList<>();
27 |
28 | static class Event {
29 | final Level level;
30 | final String message;
31 |
32 | Event(Level level, String message) {
33 | this.level = level;
34 | this.message = message;
35 | }
36 |
37 | @Override
38 | public String toString() {
39 | return "Event{" +
40 | "level=" + level +
41 | ", message='" + message + '\'' +
42 | '}';
43 | }
44 |
45 | @Override
46 | public boolean equals(Object o) {
47 | if (this == o) return true;
48 | if (o == null || getClass() != o.getClass()) return false;
49 | Event event = (Event) o;
50 | return level.equals(event.level) &&
51 | message.equals(event.message);
52 | }
53 |
54 | @Override
55 | public int hashCode() {
56 | return Objects.hash(level, message);
57 | }
58 | }
59 |
60 | TestLogger(String name) {
61 | super(name, null);
62 | }
63 |
64 | @Override
65 | public void log(Level level, String msg) {
66 | events.add(new Event(level, msg));
67 | }
68 |
69 | List getAndClearEvents() {
70 | List result = new ArrayList<>(events);
71 | events.clear();
72 | return result;
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/maple-airlift/src/test/java/io/soabase/maple/airlift/TestLogging.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Jordan Zimmerman
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 | package io.soabase.maple.airlift;
17 |
18 | import org.junit.jupiter.api.Test;
19 |
20 | import java.util.logging.Level;
21 | import java.util.logging.LogManager;
22 |
23 | import static org.assertj.core.api.Assertions.assertThat;
24 |
25 | class TestLogging {
26 | @Test
27 | void testBasic() {
28 | TestLogger testLogger = new TestLogger("test-basic");
29 | LogManager.getLogManager().addLogger(testLogger);
30 | MapleLogger logger = MapleFactory.getLogger("test-basic", Schema.class);
31 | logger.info(s -> s.name("me").age(24));
32 | assertThat(testLogger.getAndClearEvents()).containsExactly(new TestLogger.Event(Level.INFO, "age=24 name=me"));
33 |
34 | logger.logger().error("this is a test");
35 | assertThat(testLogger.getAndClearEvents()).containsExactly(new TestLogger.Event(Level.SEVERE, "this is a test"));
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/maple-benchmarks/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | io.soabase.maple
5 | maple-parent
6 | 3.2-SNAPSHOT
7 |
8 | 4.0.0
9 |
10 | maple-benchmarks
11 |
12 |
13 |
14 | org.openjdk.jmh
15 | jmh-core
16 |
17 |
18 |
19 | org.openjdk.jmh
20 | jmh-generator-annprocess
21 |
22 |
23 |
24 | io.soabase.maple
25 | maple-slf4j
26 |
27 |
28 |
29 | org.slf4j
30 | slf4j-api
31 |
32 |
33 |
34 | ch.qos.logback
35 | logback-classic
36 |
37 |
38 |
39 |
40 |
41 |
42 | org.apache.maven.plugins
43 | maven-pmd-plugin
44 |
45 | true
46 |
47 |
48 |
49 |
50 | org.apache.maven.plugins
51 | maven-deploy-plugin
52 |
53 | true
54 |
55 |
56 |
57 |
58 | org.codehaus.mojo
59 | exec-maven-plugin
60 |
61 |
62 |
63 | exec
64 |
65 | none
66 |
67 |
68 |
69 | java
70 |
71 | -classpath
72 |
73 | org.openjdk.jmh.Main
74 | -f
75 | 3
76 |
77 |
78 |
79 |
80 |
81 |
82 |
--------------------------------------------------------------------------------
/maple-benchmarks/src/main/java/io/soabase/maple/benchmarks/FakeAppender.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Jordan Zimmerman
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 | package io.soabase.maple.benchmarks;
17 |
18 | import ch.qos.logback.core.OutputStreamAppender;
19 |
20 | import java.io.OutputStream;
21 |
22 | public class FakeAppender extends OutputStreamAppender {
23 | @Override
24 | public void start() {
25 | OutputStream nop = new OutputStream() {
26 | @Override
27 | public void write(int b) {
28 | // NOP
29 | }
30 | };
31 | setOutputStream(nop);
32 | super.start();
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/maple-benchmarks/src/main/java/io/soabase/maple/benchmarks/Schema.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Jordan Zimmerman
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 | package io.soabase.maple.benchmarks;
17 |
18 | public interface Schema {
19 | Schema id(String id);
20 |
21 | Schema qty(int qty);
22 | }
23 |
--------------------------------------------------------------------------------
/maple-benchmarks/src/main/java/io/soabase/maple/benchmarks/StandardLoggerBenchmark.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Jordan Zimmerman
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 | package io.soabase.maple.benchmarks;
17 |
18 | import org.openjdk.jmh.annotations.Benchmark;
19 | import org.slf4j.Logger;
20 | import org.slf4j.LoggerFactory;
21 |
22 | public class StandardLoggerBenchmark {
23 | private static final Logger savedLogger = getLogger();
24 |
25 | @Benchmark
26 | public void testFreshLogger() {
27 | testAllLevels(getLogger());
28 | }
29 |
30 | @Benchmark
31 | public void testSavedLogger() {
32 | testAllLevels(savedLogger);
33 | }
34 |
35 | private static Logger getLogger() {
36 | return LoggerFactory.getLogger(StandardLoggerBenchmark.class);
37 | }
38 |
39 | private void testAllLevels(Logger logger) {
40 | logger.trace("message id={} qty={}", Utils.str(), Utils.value());
41 | logger.warn("message id={} qty={}", Utils.str(), Utils.value());
42 | logger.debug("message id={} qty={}", Utils.str(), Utils.value());
43 | logger.error("message id={} qty={}", Utils.str(), Utils.value());
44 | logger.info("message id={} qty={}", Utils.str(), Utils.value());
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/maple-benchmarks/src/main/java/io/soabase/maple/benchmarks/StructuredLoggerBenchmark.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Jordan Zimmerman
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 | package io.soabase.maple.benchmarks;
17 |
18 | import io.soabase.maple.slf4j.MapleFactory;
19 | import io.soabase.maple.slf4j.MapleLogger;
20 | import org.openjdk.jmh.annotations.Benchmark;
21 |
22 | public class StructuredLoggerBenchmark {
23 | private static final MapleLogger savedLogger = getLogger();
24 |
25 | @Benchmark
26 | public void testFreshLogger() {
27 | testAllLevels(getLogger());
28 | }
29 |
30 | @Benchmark
31 | public void testSavedLogger() {
32 | testAllLevels(savedLogger);
33 | }
34 |
35 | private static MapleLogger getLogger() {
36 | return MapleFactory.getLogger(StructuredLoggerBenchmark.class, Schema.class);
37 | }
38 |
39 | private void testAllLevels(MapleLogger logger) {
40 | logger.trace("message", schema -> schema.id(Utils.str()).qty(Utils.value()));
41 | logger.warn("message", schema -> schema.id(Utils.str()).qty(Utils.value()));
42 | logger.debug("message", schema -> schema.id(Utils.str()).qty(Utils.value()));
43 | logger.error("message", schema -> schema.id(Utils.str()).qty(Utils.value()));
44 | logger.info("message", schema -> schema.id(Utils.str()).qty(Utils.value()));
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/maple-benchmarks/src/main/java/io/soabase/maple/benchmarks/Utils.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Jordan Zimmerman
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 | package io.soabase.maple.benchmarks;
17 |
18 | import java.util.concurrent.ThreadLocalRandom;
19 |
20 | class Utils {
21 | static String str() {
22 | return Long.toString(ThreadLocalRandom.current().nextLong());
23 | }
24 |
25 | static int value() {
26 | return ThreadLocalRandom.current().nextInt();
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/maple-benchmarks/src/main/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
19 |
20 |
21 |
22 | %d{HH:mm:ss.SSS} [%-5level] %logger{15} - %msg%n%rEx
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/maple-core/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | io.soabase.maple
5 | maple-parent
6 | 3.2-SNAPSHOT
7 |
8 | 4.0.0
9 |
10 | maple-core
11 |
12 |
13 |
14 | net.bytebuddy
15 | byte-buddy
16 |
17 |
18 |
19 | com.fasterxml.jackson.core
20 | jackson-databind
21 | provided
22 |
23 |
24 |
25 | org.junit.jupiter
26 | junit-jupiter
27 | test
28 |
29 |
30 |
31 | org.assertj
32 | assertj-core
33 | test
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/maple-core/src/main/java/io/soabase/maple/api/LevelLogger.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Jordan Zimmerman
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 | package io.soabase.maple.api;
17 |
18 | @FunctionalInterface
19 | public interface LevelLogger {
20 | void log(String msg, Throwable t);
21 | }
22 |
--------------------------------------------------------------------------------
/maple-core/src/main/java/io/soabase/maple/api/LoggingLevel.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Jordan Zimmerman
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 | package io.soabase.maple.api;
17 |
18 | public enum LoggingLevel {
19 | ERROR,
20 | WARN,
21 | INFO,
22 | DEBUG,
23 | TRACE
24 | }
25 |
--------------------------------------------------------------------------------
/maple-core/src/main/java/io/soabase/maple/api/MapleFormatter.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Jordan Zimmerman
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 | package io.soabase.maple.api;
17 |
18 | /**
19 | * Responsible for taking generated name/value pairs and calling the underlying logger
20 | */
21 | @FunctionalInterface
22 | public interface MapleFormatter {
23 | /**
24 | * Apply generated name/value pairs and calling the underlying logger
25 | * @param logger the logger proxy
26 | * @param loggingLevel the logging level
27 | * @param loggerName the name of the logger
28 | * @param namesValues name/value pairs
29 | * @param mainMessage the main message to output or {@code ""}
30 | * @param t the exception to output or {@code null}
31 | */
32 | void apply(LevelLogger logger, LoggingLevel loggingLevel, String loggerName, NamesValues namesValues, String mainMessage, Throwable t);
33 | }
34 |
--------------------------------------------------------------------------------
/maple-core/src/main/java/io/soabase/maple/api/MapleLoggerApi.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Jordan Zimmerman
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 | package io.soabase.maple.api;
17 |
18 | public interface MapleLoggerApi {
19 | /**
20 | * If the log level is TRACE, complete the statement using a generated schema
21 | * instance, pass the generated name/values to the current logging formatter
22 | * which will then log via the underlying logging system.
23 | *
24 | * @param statement structured logging statement
25 | */
26 | void trace(Statement statement);
27 |
28 | /**
29 | * If the log level is DEBUG, complete the statement using a generated schema
30 | * instance, pass the generated name/values to the current logging formatter
31 | * which will then log via the underlying logging system.
32 | *
33 | * @param statement structured logging statement
34 | */
35 | void debug(Statement statement);
36 |
37 | /**
38 | * If the log level is WARN, complete the statement using a generated schema
39 | * instance, pass the generated name/values to the current logging formatter
40 | * which will then log via the underlying logging system.
41 | *
42 | * @param statement structured logging statement
43 | */
44 | void warn(Statement statement);
45 |
46 | /**
47 | * If the log level is INFO, complete the statement using a generated schema
48 | * instance, pass the generated name/values to the current logging formatter
49 | * which will then log via the underlying logging system.
50 | *
51 | * @param statement structured logging statement
52 | */
53 | void info(Statement statement);
54 |
55 | /**
56 | * If the log level is ERROR, complete the statement using a generated schema
57 | * instance, pass the generated name/values to the current logging formatter
58 | * which will then log via the underlying logging system.
59 | *
60 | * @param statement structured logging statement
61 | */
62 | void error(Statement statement);
63 |
64 | /**
65 | * If the log level is TRACE, complete the statement using a generated schema
66 | * instance, pass the generated name/values to the current logging formatter
67 | * which will then log via the underlying logging system.
68 | *
69 | * @param mainMessage passed as the main message to the logging formatter - cannot be {@code null}
70 | * @param statement structured logging statement
71 | */
72 | void trace(String mainMessage, Statement statement);
73 |
74 | /**
75 | * If the log level is DEBUG, complete the statement using a generated schema
76 | * instance, pass the generated name/values to the current logging formatter
77 | * which will then log via the underlying logging system.
78 | *
79 | * @param mainMessage passed as the main message to the logging formatter - cannot be {@code null}
80 | * @param statement structured logging statement
81 | */
82 | void debug(String mainMessage, Statement statement);
83 |
84 | /**
85 | * If the log level is WARN, complete the statement using a generated schema
86 | * instance, pass the generated name/values to the current logging formatter
87 | * which will then log via the underlying logging system.
88 | *
89 | * @param mainMessage passed as the main message to the logging formatter - cannot be {@code null}
90 | * @param statement structured logging statement
91 | */
92 | void warn(String mainMessage, Statement statement);
93 |
94 | /**
95 | * If the log level is INFO, complete the statement using a generated schema
96 | * instance, pass the generated name/values to the current logging formatter
97 | * which will then log via the underlying logging system.
98 | *
99 | * @param mainMessage passed as the main message to the logging formatter - cannot be {@code null}
100 | * @param statement structured logging statement
101 | */
102 | void info(String mainMessage, Statement statement);
103 |
104 | /**
105 | * If the log level is ERROR, complete the statement using a generated schema
106 | * instance, pass the generated name/values to the current logging formatter
107 | * which will then log via the underlying logging system.
108 | *
109 | * @param mainMessage passed as the main message to the logging formatter - cannot be {@code null}
110 | * @param statement structured logging statement
111 | */
112 | void error(String mainMessage, Statement statement);
113 |
114 | /**
115 | * If the log level is TRACE, complete the statement using a generated schema
116 | * instance, pass the generated name/values to the current logging formatter
117 | * which will then log via the underlying logging system.
118 | *
119 | * @param t passed as the exception to the logging formatter - can be {@code null}
120 | * @param statement structured logging statement
121 | */
122 | void trace(Throwable t, Statement statement);
123 |
124 | /**
125 | * If the log level is DEBUG, complete the statement using a generated schema
126 | * instance, pass the generated name/values to the current logging formatter
127 | * which will then log via the underlying logging system.
128 | *
129 | * @param t passed as the exception to the logging formatter - can be {@code null}
130 | * @param statement structured logging statement
131 | */
132 | void debug(Throwable t, Statement statement);
133 |
134 | /**
135 | * If the log level is WARN, complete the statement using a generated schema
136 | * instance, pass the generated name/values to the current logging formatter
137 | * which will then log via the underlying logging system.
138 | *
139 | * @param t passed as the exception to the logging formatter - can be {@code null}
140 | * @param statement structured logging statement
141 | */
142 | void warn(Throwable t, Statement statement);
143 |
144 | /**
145 | * If the log level is INFO, complete the statement using a generated schema
146 | * instance, pass the generated name/values to the current logging formatter
147 | * which will then log via the underlying logging system.
148 | *
149 | * @param t passed as the exception to the logging formatter - can be {@code null}
150 | * @param statement structured logging statement
151 | */
152 | void info(Throwable t, Statement statement);
153 |
154 | /**
155 | * If the log level is ERROR, complete the statement using a generated schema
156 | * instance, pass the generated name/values to the current logging formatter
157 | * which will then log via the underlying logging system.
158 | *
159 | * @param t passed as the exception to the logging formatter - can be {@code null}
160 | * @param statement structured logging statement
161 | */
162 | void error(Throwable t, Statement statement);
163 |
164 | /**
165 | * If the log level is TRACE, complete the statement using a generated schema
166 | * instance, pass the generated name/values to the current logging formatter
167 | * which will then log via the underlying logging system.
168 | *
169 | * @param mainMessage passed as the main message to the logging formatter - cannot be {@code null}
170 | * @param t passed as the exception to the logging formatter - can be {@code null}
171 | * @param statement structured logging statement
172 | */
173 | void trace(String mainMessage, Throwable t, Statement statement);
174 |
175 | /**
176 | * If the log level is DEBUG, complete the statement using a generated schema
177 | * instance, pass the generated name/values to the current logging formatter
178 | * which will then log via the underlying logging system.
179 | *
180 | * @param mainMessage passed as the main message to the logging formatter - cannot be {@code null}
181 | * @param t passed as the exception to the logging formatter - can be {@code null}
182 | * @param statement structured logging statement
183 | */
184 | void debug(String mainMessage, Throwable t, Statement statement);
185 |
186 | /**
187 | * If the log level is WARN, complete the statement using a generated schema
188 | * instance, pass the generated name/values to the current logging formatter
189 | * which will then log via the underlying logging system.
190 | *
191 | * @param mainMessage passed as the main message to the logging formatter - cannot be {@code null}
192 | * @param t passed as the exception to the logging formatter - can be {@code null}
193 | * @param statement structured logging statement
194 | */
195 | void warn(String mainMessage, Throwable t, Statement statement);
196 |
197 | /**
198 | * If the log level is INFO, complete the statement using a generated schema
199 | * instance, pass the generated name/values to the current logging formatter
200 | * which will then log via the underlying logging system.
201 | *
202 | * @param mainMessage passed as the main message to the logging formatter - cannot be {@code null}
203 | * @param t passed as the exception to the logging formatter - can be {@code null}
204 | * @param statement structured logging statement
205 | */
206 | void info(String mainMessage, Throwable t, Statement statement);
207 |
208 | /**
209 | * If the log level is ERROR, complete the statement using a generated schema
210 | * instance, pass the generated name/values to the current logging formatter
211 | * which will then log via the underlying logging system.
212 | *
213 | * @param mainMessage passed as the main message to the logging formatter - cannot be {@code null}
214 | * @param t passed as the exception to the logging formatter - can be {@code null}
215 | * @param statement structured logging statement
216 | */
217 | void error(String mainMessage, Throwable t, Statement statement);
218 |
219 | /**
220 | * Pass the generated name/values to the logger's MDC system
221 | *
222 | * @param statement structured logging statement
223 | * @return a closeable - when closed the schema names are removed from MDC
224 | */
225 | MdcCloseable mdc(Statement statement);
226 | }
227 |
--------------------------------------------------------------------------------
/maple-core/src/main/java/io/soabase/maple/api/MdcCloseable.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Jordan Zimmerman
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 | package io.soabase.maple.api;
17 |
18 | public interface MdcCloseable extends AutoCloseable {
19 | void close();
20 | }
21 |
--------------------------------------------------------------------------------
/maple-core/src/main/java/io/soabase/maple/api/NameValue.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Jordan Zimmerman
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 | package io.soabase.maple.api;
17 |
18 | public interface NameValue {
19 | String name();
20 |
21 | Object value();
22 | }
23 |
--------------------------------------------------------------------------------
/maple-core/src/main/java/io/soabase/maple/api/Names.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Jordan Zimmerman
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 | package io.soabase.maple.api;
17 |
18 | import java.util.Set;
19 |
20 | public interface Names {
21 | int qty();
22 |
23 | String nthName(int n);
24 |
25 | String nthRawName(int n);
26 |
27 | Set nthSpecializations(int n);
28 | }
29 |
--------------------------------------------------------------------------------
/maple-core/src/main/java/io/soabase/maple/api/NamesValues.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Jordan Zimmerman
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 | package io.soabase.maple.api;
17 |
18 | import java.util.stream.Stream;
19 |
20 | public interface NamesValues extends Names, Values {
21 | /**
22 | * Utility - return a stream of the name/value pairs
23 | *
24 | * @return stream of name/value
25 | */
26 | Stream stream();
27 | }
28 |
--------------------------------------------------------------------------------
/maple-core/src/main/java/io/soabase/maple/api/Specialization.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Jordan Zimmerman
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 | package io.soabase.maple.api;
17 |
18 | public enum Specialization {
19 | REQUIRED,
20 | DEFAULT_FROM_MDC
21 | }
22 |
--------------------------------------------------------------------------------
/maple-core/src/main/java/io/soabase/maple/api/Statement.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Jordan Zimmerman
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 | package io.soabase.maple.api;
17 |
18 | import io.soabase.maple.spi.MetaInstance;
19 |
20 | import java.util.stream.Stream;
21 |
22 | /**
23 | * Consumer of logging schema instances.
24 | */
25 | @FunctionalInterface
26 | public interface Statement {
27 | void handle(T schemaInstance);
28 |
29 | /**
30 | * Chain statements together to achieve partial logging, composed logging, etc. E.g.
31 | *
32 | *
33 | * // partialLog is "pre filled" with fields/values
34 | * Statement<LoggingSchema> partialLog = s -> s.event(UPDATE).customerId(customerId);
35 | *
36 | * ... later ...
37 | *
38 | * // partialLog is used along with the additional field "eventDetail"
39 | * logger.info(partialLog.concat(s -> s.eventDetail("success"));
40 | *
41 | *
42 | * @param partialStatement - statement to concat
43 | * @return new composed statement
44 | */
45 | default Statement concat(Statement partialStatement) {
46 | return schemaInstance -> {
47 | handle(schemaInstance);
48 | partialStatement.handle(schemaInstance);
49 | };
50 | }
51 |
52 | /**
53 | * Utility - given a meta instance, apply this statement to produce a names/values instance
54 | *
55 | * @param metaInstance meta instance
56 | * @return names/values
57 | */
58 | default NamesValues toNamesValues(MetaInstance metaInstance) {
59 | T instance = metaInstance.newSchemaInstance();
60 | handle(instance);
61 | return metaInstance.toNamesValues(instance);
62 | }
63 |
64 | /**
65 | * Utility, given a meta instance, apply this statement to produce a names/values instance
66 | * and return a stream of each name/value pair
67 | *
68 | * @param metaInstance meta instance
69 | * @return stream of names/values
70 | */
71 | default Stream stream(MetaInstance metaInstance) {
72 | return toNamesValues(metaInstance).stream();
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/maple-core/src/main/java/io/soabase/maple/api/Values.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Jordan Zimmerman
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 | package io.soabase.maple.api;
17 |
18 | @FunctionalInterface
19 | public interface Values {
20 | Object nthValue(int n);
21 | }
22 |
--------------------------------------------------------------------------------
/maple-core/src/main/java/io/soabase/maple/api/annotations/DoNotLog.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Jordan Zimmerman
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 | package io.soabase.maple.api.annotations;
17 |
18 | import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
19 | import com.fasterxml.jackson.annotation.JsonIgnore;
20 |
21 | import java.lang.annotation.ElementType;
22 | import java.lang.annotation.Retention;
23 | import java.lang.annotation.RetentionPolicy;
24 | import java.lang.annotation.Target;
25 |
26 | /**
27 | * Can be used with {@link io.soabase.maple.api.MapleFormatter}s that use Jackson
28 | * (e.g. {@link io.soabase.maple.formatters.ModelFormatter}. Fields annotated with this
29 | * will not get logged. For example, mark password fields or any other security sensitive fields.
30 | */
31 | @Retention(RetentionPolicy.RUNTIME)
32 | @Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.FIELD})
33 | @JacksonAnnotationsInside
34 | @JsonIgnore
35 | public @interface DoNotLog {
36 | }
37 |
--------------------------------------------------------------------------------
/maple-core/src/main/java/io/soabase/maple/api/annotations/MdcDefaultValue.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Jordan Zimmerman
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 | package io.soabase.maple.api.annotations;
17 |
18 | import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
19 | import com.fasterxml.jackson.annotation.JsonIgnore;
20 |
21 | import java.lang.annotation.ElementType;
22 | import java.lang.annotation.Retention;
23 | import java.lang.annotation.RetentionPolicy;
24 | import java.lang.annotation.Target;
25 |
26 | /**
27 | * You can annotate schema methods with {@code @MdcDefaultValue}. For these methods if you do not specify a value directly,
28 | * Maple will look in the MDC for the value
29 | */
30 | @Retention(RetentionPolicy.RUNTIME)
31 | @Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.FIELD})
32 | @JacksonAnnotationsInside
33 | @JsonIgnore
34 | public @interface MdcDefaultValue {
35 | }
36 |
--------------------------------------------------------------------------------
/maple-core/src/main/java/io/soabase/maple/api/annotations/Required.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Jordan Zimmerman
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 | package io.soabase.maple.api.annotations;
17 |
18 | import java.lang.annotation.ElementType;
19 | import java.lang.annotation.Retention;
20 | import java.lang.annotation.RetentionPolicy;
21 | import java.lang.annotation.Target;
22 |
23 | /**
24 | * Marks a schema method as being required. If a value is not set for it
25 | * then log statements will throw {@link io.soabase.maple.api.exceptions.MissingSchemaValueException}.
26 | * Note: for production, etc. you can disable these checks via
27 | * {@link io.soabase.maple.spi.MapleSpi#setProductionMode(boolean)}
28 | */
29 | @Retention(RetentionPolicy.RUNTIME)
30 | @Target(ElementType.METHOD)
31 | public @interface Required {
32 | }
33 |
--------------------------------------------------------------------------------
/maple-core/src/main/java/io/soabase/maple/api/annotations/SortOrder.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Jordan Zimmerman
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 | package io.soabase.maple.api.annotations;
17 |
18 | import java.lang.annotation.ElementType;
19 | import java.lang.annotation.Retention;
20 | import java.lang.annotation.RetentionPolicy;
21 | import java.lang.annotation.Target;
22 |
23 | /**
24 | * Normally, schema fields are ordered alphabetically. Annotate methods
25 | * with SortOrder to influence sorting. Lower values sort first. Note: the default
26 | * sort value for un-annotated methods is {@link Short#MAX_VALUE}.
27 | */
28 | @Retention(RetentionPolicy.RUNTIME)
29 | @Target(ElementType.METHOD)
30 | public @interface SortOrder {
31 | int value();
32 | }
33 |
--------------------------------------------------------------------------------
/maple-core/src/main/java/io/soabase/maple/api/exceptions/InvalidSchemaException.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Jordan Zimmerman
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 | package io.soabase.maple.api.exceptions;
17 |
18 | /**
19 | * Thrown during schema generation when the schema class is invalid for some reason
20 | */
21 | public class InvalidSchemaException extends RuntimeException {
22 | public InvalidSchemaException(String message) {
23 | super(message);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/maple-core/src/main/java/io/soabase/maple/api/exceptions/MissingSchemaValueException.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Jordan Zimmerman
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 | package io.soabase.maple.api.exceptions;
17 |
18 | public class MissingSchemaValueException extends RuntimeException {
19 | public MissingSchemaValueException(String message) {
20 | super(message);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/maple-core/src/main/java/io/soabase/maple/core/GeneratedMetaInstance.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Jordan Zimmerman
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 | package io.soabase.maple.core;
17 |
18 | import io.soabase.maple.api.MapleFormatter;
19 | import io.soabase.maple.api.Names;
20 | import io.soabase.maple.api.NamesValues;
21 | import io.soabase.maple.spi.MetaInstance;
22 |
23 | class GeneratedMetaInstance implements MetaInstance {
24 | private final Class generatedClass;
25 | private final InstanceFactory instanceFactory;
26 | private final Names names;
27 | private final MapleFormatter formatter;
28 |
29 | GeneratedMetaInstance(Class generatedClass, InstanceFactory instanceFactory, Names names, MapleFormatter formatter) {
30 | this.generatedClass = generatedClass;
31 | this.instanceFactory = instanceFactory;
32 | this.names = names;
33 | this.formatter = formatter;
34 | }
35 |
36 | @Override
37 | public T newSchemaInstance() {
38 | try {
39 | T instance = instanceFactory.newInstance();
40 | ((Instance) instance).arguments = new Object[names.qty()];
41 | return instance;
42 | } catch (Exception e) {
43 | throw new RuntimeException("Could not allocate schema instance: " + generatedClass.getName(), e);
44 | }
45 | }
46 |
47 | @Override
48 | public Names schemaNames() {
49 | return names;
50 | }
51 |
52 | @Override
53 | public MapleFormatter formatter() {
54 | return formatter;
55 | }
56 |
57 | @Override
58 | public NamesValues toNamesValues(T instance) {
59 | return new NamesValuesImp(names, ((Instance) instance).arguments);
60 | }
61 |
62 | }
63 |
--------------------------------------------------------------------------------
/maple-core/src/main/java/io/soabase/maple/core/Generator.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Jordan Zimmerman
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 | package io.soabase.maple.core;
17 |
18 | import io.soabase.maple.api.MapleFormatter;
19 | import io.soabase.maple.api.Names;
20 | import io.soabase.maple.api.exceptions.InvalidSchemaException;
21 | import net.bytebuddy.ByteBuddy;
22 | import net.bytebuddy.dynamic.DynamicType;
23 | import net.bytebuddy.implementation.FixedValue;
24 | import net.bytebuddy.implementation.Implementation;
25 | import net.bytebuddy.implementation.MethodDelegation;
26 | import net.bytebuddy.matcher.ElementMatcher;
27 |
28 | import java.lang.reflect.Method;
29 | import java.lang.reflect.Modifier;
30 | import java.util.*;
31 | import java.util.concurrent.ConcurrentHashMap;
32 | import java.util.stream.Collectors;
33 | import java.util.stream.IntStream;
34 | import java.util.stream.Stream;
35 |
36 | import static net.bytebuddy.implementation.MethodCall.invoke;
37 | import static net.bytebuddy.matcher.ElementMatchers.named;
38 | import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
39 |
40 | public class Generator {
41 | private final Map metaInstanceCache = new ConcurrentHashMap<>();
42 | private final Map generatedCache = new ConcurrentHashMap<>();
43 | private static final Set reservedMethodNames = Collections.unmodifiableSet(
44 | Stream.of(Instance.class.getMethods()).map(Method::getName).collect(Collectors.toSet())
45 | );
46 | private static final Method setValueAtIndexMethod;
47 |
48 | static {
49 | try {
50 | setValueAtIndexMethod = Instance.class.getMethod("internalSetValueAtIndex", Integer.TYPE, Object.class);
51 | } catch (NoSuchMethodException e) {
52 | throw new RuntimeException("Could not find internal method", e);
53 | }
54 | }
55 |
56 | public static Set getReservedMethodNames() {
57 | return reservedMethodNames;
58 | }
59 |
60 | public void clearCache() {
61 | metaInstanceCache.clear();
62 | generatedCache.clear();
63 | }
64 |
65 | private static class Generated {
66 | final Class generatedClass;
67 | final InstanceFactory instanceFactory;
68 |
69 | Generated(Class generatedClass, InstanceFactory instanceFactory) {
70 | this.generatedClass = generatedClass;
71 | this.instanceFactory = instanceFactory;
72 | }
73 | }
74 |
75 | @SuppressWarnings("unchecked")
76 | public GeneratedMetaInstance generate(Names names, Class schemaClass, ClassLoader classLoader, MapleFormatter formatter) {
77 | return metaInstanceCache.computeIfAbsent(new Key(schemaClass, formatter), __ -> {
78 | Generated generated = generatedCache.computeIfAbsent(schemaClass, ___ -> {
79 | ByteBuddy byteBuddy = new ByteBuddy();
80 | Class generatedClass = internalGenerate(byteBuddy, schemaClass, classLoader, toMap(names));
81 | InstanceFactory instanceFactory = generateInstanceFactory(byteBuddy, generatedClass);
82 | return new Generated(generatedClass, instanceFactory);
83 | });
84 | return new GeneratedMetaInstance<>(generated.generatedClass, generated.instanceFactory, names, formatter);
85 | });
86 | }
87 |
88 | private Map toMap(Names names) {
89 | return IntStream.range(0, names.qty())
90 | .mapToObj(i -> new AbstractMap.SimpleEntry<>(names.nthRawName(i), i))
91 | .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
92 | }
93 |
94 | private Class internalGenerate(ByteBuddy byteBuddy, Class schemaClass, ClassLoader classLoader, Map names) {
95 | DynamicType.Builder builder = byteBuddy.subclass(Instance.class).implement(schemaClass);
96 | for (Method method : schemaClass.getMethods()) {
97 | if (method.isBridge() || method.isSynthetic() || method.isDefault() || Modifier.isStatic(method.getModifiers())) {
98 | continue;
99 | }
100 | int thisIndex = names.getOrDefault(method.toGenericString(), -1);
101 | if (thisIndex < 0 ) {
102 | throw new InvalidSchemaException(String.format("Could not find method %s in generated Names", method.toGenericString()));
103 | }
104 | Implementation methodCall = invoke(setValueAtIndexMethod)
105 | .with(thisIndex)
106 | .withArgument(0)
107 | .andThen(FixedValue.self());
108 | ElementMatcher> matcher = named(method.getName())
109 | .and(takesArguments(method.getParameterTypes()[0]));
110 | builder = builder.method(matcher).intercept(methodCall);
111 | }
112 | return builder.make().load(classLoader).getLoaded();
113 | }
114 |
115 | private InstanceFactory generateInstanceFactory(ByteBuddy byteBuddy, Class clazz) {
116 | try {
117 | DynamicType.Builder builder = byteBuddy
118 | .subclass(InstanceFactory.class)
119 | .method(named("newInstance")).intercept(MethodDelegation.toConstructor(clazz));
120 | return builder.make().load(clazz.getClassLoader()).getLoaded().getDeclaredConstructor().newInstance();
121 | } catch (Exception e) {
122 | throw new RuntimeException("Couldn't not create InstanceFactory for: " + clazz.getName(), e);
123 | }
124 | }
125 | }
126 |
--------------------------------------------------------------------------------
/maple-core/src/main/java/io/soabase/maple/core/Instance.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Jordan Zimmerman
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 | package io.soabase.maple.core;
17 |
18 | // note: this is public so that ByteBuddy can access it
19 | @SuppressWarnings("WeakerAccess")
20 | public class Instance {
21 | Object[] arguments;
22 |
23 | public void internalSetValueAtIndex(int index, Object value) {
24 | arguments[index] = value;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/maple-core/src/main/java/io/soabase/maple/core/InstanceFactory.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Jordan Zimmerman
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 | package io.soabase.maple.core;
17 |
18 | // note: this is public so that ByteBuddy can access it
19 | @FunctionalInterface
20 | public interface InstanceFactory {
21 | T newInstance();
22 | }
23 |
--------------------------------------------------------------------------------
/maple-core/src/main/java/io/soabase/maple/core/Key.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Jordan Zimmerman
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 | package io.soabase.maple.core;
17 |
18 | import io.soabase.maple.api.MapleFormatter;
19 |
20 | // TODO(test different combinations of schema class and logging formatter)
21 | class Key {
22 | private final Class clazz;
23 | private final MapleFormatter formatter;
24 | private final int hash;
25 |
26 | Key(Class clazz, MapleFormatter formatter) {
27 | this.clazz = clazz;
28 | this.formatter = formatter;
29 | hash = calcHash();
30 | }
31 |
32 | @Override
33 | public boolean equals(Object o) {
34 | if (this == o){
35 | return true;
36 | }
37 | if (o == null || getClass() != o.getClass()){
38 | return false;
39 | }
40 |
41 | Key key = (Key) o;
42 |
43 | if (!clazz.equals(key.clazz)){
44 | return false;
45 | }
46 | return formatter.equals(key.formatter);
47 | }
48 |
49 | @Override
50 | public int hashCode() {
51 | return hash;
52 | }
53 |
54 | private int calcHash() {
55 | int result = clazz.hashCode();
56 | result = 31 * result + formatter.hashCode();
57 | return result;
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/maple-core/src/main/java/io/soabase/maple/core/MapleLoggerBase.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Jordan Zimmerman
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 | package io.soabase.maple.core;
17 |
18 | import io.soabase.maple.api.LoggingLevel;
19 | import io.soabase.maple.api.MapleLoggerApi;
20 | import io.soabase.maple.api.Statement;
21 |
22 | public interface MapleLoggerBase extends MapleLoggerApi {
23 | default void trace(Statement statement) {
24 | consume(LoggingLevel.TRACE, "", null, statement);
25 | }
26 |
27 | default void debug(Statement statement) {
28 | consume(LoggingLevel.DEBUG, "", null, statement);
29 | }
30 |
31 | default void warn(Statement statement) {
32 | consume(LoggingLevel.WARN, "", null, statement);
33 | }
34 |
35 | default void info(Statement statement) {
36 | consume(LoggingLevel.INFO, "", null, statement);
37 | }
38 |
39 | default void error(Statement statement) {
40 | consume(LoggingLevel.ERROR, "", null, statement);
41 | }
42 |
43 | default void trace(String mainMessage, Statement statement) {
44 | consume(LoggingLevel.TRACE, mainMessage, null, statement);
45 | }
46 |
47 | default void debug(String mainMessage, Statement statement) {
48 | consume(LoggingLevel.DEBUG, mainMessage, null, statement);
49 | }
50 |
51 | default void warn(String mainMessage, Statement statement) {
52 | consume(LoggingLevel.WARN, mainMessage, null, statement);
53 | }
54 |
55 | default void info(String mainMessage, Statement statement) {
56 | consume(LoggingLevel.INFO, mainMessage, null, statement);
57 | }
58 |
59 | default void error(String mainMessage, Statement statement) {
60 | consume(LoggingLevel.ERROR, mainMessage, null, statement);
61 | }
62 |
63 | default void trace(Throwable t, Statement statement) {
64 | consume(LoggingLevel.TRACE, "", t, statement);
65 | }
66 |
67 | default void debug(Throwable t, Statement statement) {
68 | debug("", t, statement);
69 | }
70 |
71 | default void warn(Throwable t, Statement statement) {
72 | consume(LoggingLevel.WARN, "", t, statement);
73 | }
74 |
75 | default void info(Throwable t, Statement statement) {
76 | consume(LoggingLevel.INFO, "", t, statement);
77 | }
78 |
79 | default void error(Throwable t, Statement statement) {
80 | consume(LoggingLevel.ERROR, "", t, statement);
81 | }
82 |
83 | default void trace(String mainMessage, Throwable t, Statement statement) {
84 | consume(LoggingLevel.TRACE, mainMessage, t, statement);
85 | }
86 |
87 | default void debug(String mainMessage, Throwable t, Statement statement) {
88 | consume(LoggingLevel.DEBUG, mainMessage, t, statement);
89 | }
90 |
91 | default void warn(String mainMessage, Throwable t, Statement statement) {
92 | consume(LoggingLevel.WARN, mainMessage, t, statement);
93 | }
94 |
95 | default void info(String mainMessage, Throwable t, Statement statement) {
96 | consume(LoggingLevel.INFO, mainMessage, t, statement);
97 | }
98 |
99 | default void error(String mainMessage, Throwable t, Statement statement) {
100 | consume(LoggingLevel.ERROR, mainMessage, t, statement);
101 | }
102 |
103 | void consume(LoggingLevel loggingLevel, String mainMessage, Throwable t, Statement statement);
104 | }
105 |
--------------------------------------------------------------------------------
/maple-core/src/main/java/io/soabase/maple/core/NamesValuesImp.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Jordan Zimmerman
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 | package io.soabase.maple.core;
17 |
18 | import io.soabase.maple.api.NameValue;
19 | import io.soabase.maple.api.Names;
20 | import io.soabase.maple.api.NamesValues;
21 | import io.soabase.maple.api.Specialization;
22 |
23 | import java.util.Iterator;
24 | import java.util.Set;
25 | import java.util.Spliterator;
26 | import java.util.Spliterators;
27 | import java.util.stream.Stream;
28 | import java.util.stream.StreamSupport;
29 |
30 | class NamesValuesImp implements NamesValues {
31 | private final Names names;
32 | private final Object[] arguments;
33 |
34 | NamesValuesImp(Names names, Object[] arguments) {
35 | this.names = names;
36 | this.arguments = arguments;
37 | }
38 |
39 | @Override
40 | public int qty() {
41 | return names.qty();
42 | }
43 |
44 | @Override
45 | public String nthName(int n) {
46 | return names.nthName(n);
47 | }
48 |
49 | @Override
50 | public String nthRawName(int n) {
51 | return names.nthRawName(n);
52 | }
53 |
54 | @Override
55 | public Object nthValue(int n) {
56 | return arguments[n];
57 | }
58 |
59 | @Override
60 | public Set nthSpecializations(int n) {
61 | return names.nthSpecializations(n);
62 | }
63 |
64 | @Override
65 | public Stream stream() {
66 | return newStream(this);
67 | }
68 |
69 | static Stream newStream(NamesValues namesValues) {
70 | Iterator iterator = new Iterator() {
71 | private int index = -1;
72 |
73 | @Override
74 | public boolean hasNext() {
75 | return (index + 1) < namesValues.qty();
76 | }
77 |
78 | @Override
79 | public NameValue next() {
80 | int thisIndex = ++index;
81 | return new NameValue() {
82 | @Override
83 | public String name() {
84 | return namesValues.nthName(thisIndex);
85 | }
86 |
87 | @Override
88 | public Object value() {
89 | return namesValues.nthValue(thisIndex);
90 | }
91 | };
92 | }
93 | };
94 | return StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, Spliterator.ORDERED), false);
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/maple-core/src/main/java/io/soabase/maple/core/SpecializedNamesValues.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Jordan Zimmerman
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 | package io.soabase.maple.core;
17 |
18 | import io.soabase.maple.api.NameValue;
19 | import io.soabase.maple.api.Names;
20 | import io.soabase.maple.api.NamesValues;
21 | import io.soabase.maple.api.Specialization;
22 |
23 | import java.util.Set;
24 | import java.util.function.IntFunction;
25 | import java.util.stream.Stream;
26 |
27 | import static io.soabase.maple.core.NamesValuesImp.newStream;
28 |
29 | public class SpecializedNamesValues implements NamesValues {
30 | private final Names names;
31 | private final IntFunction