Skip to content

Commit fef68cb

Browse files
Log API Improvements (#974)
* Add custom JSON logging support with unescaped `data` and plain `message` fields - Ensured `data` field is unescaped JSON, while `message` remains a simple String - Updated `EcsLayout.json` to include `message`, `data`, and `context` fields (or add a new template) - `context` is populated via MDC (`ThreadContext.put`) and supports simple key-value pairs * Restore some changes * New methods added * A custom resolver is added to handle messages other than MapMessages to be compatible with the existing implementation of the log (the old implementation remains unchanged). * Add a custom .json template that uses the custom resolver * Refactoring * Fix cyclic referencing of gxClassR * Fix: AndroidLogger is not abstract and does not override abstract method isEnabled * Fix: AndroidLogger is not abstract and does not override abstract methods * Remove unnecessary comment * Avoid code duplication * Uses org.json instead of Gson * Remove casting * Ensure type safety * Move it to the resources folder. When compiling it will be in the root of the jar * Rename constant to WARN * Explicitly prevent instantiation * Plugin rename * Build the message only if the loglevel is enabled * Check if the log format is JSON once. * Filters the stack trace to ignore the first lines called from this package * Refactoring * Maintain insertion order when logging JSONs * The string "null" is written as a string and not as a null object (same as in .NET) --------- Co-authored-by: claudiamurialdo <[email protected]>
1 parent 715fb6f commit fef68cb

File tree

9 files changed

+543
-63
lines changed

9 files changed

+543
-63
lines changed

common/src/main/java/com/genexus/diagnostics/Log.java

Lines changed: 21 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -7,63 +7,60 @@ public class Log {
77
private static ILogger getLogger() {
88
return getLogger("");
99
}
10-
10+
1111
public static ILogger getMainLogger() {
1212
return LogManager.getLogger("com.genexus.logging");
1313
}
14-
14+
1515
private static ILogger getLogger(String topic) {
1616
ILogger log;
1717
if (topic != null && topic.length() > 0) {
1818
log = LogManager.getLogger(topic);
19-
}
20-
else {
19+
} else {
2120
log = getMainLogger();
2221
}
2322
return log;
2423
}
25-
24+
2625
public static void write(int logLevel, String message, String topic) {
2726
write(message, topic, logLevel);
2827
}
29-
28+
3029
public static void write(String message, String topic, int logLevel) {
3130
ILogger log = getLogger(topic);
32-
33-
switch (logLevel) {
34-
case LogLevel.OFF: //LogLevel off
31+
LogLevel level = LogLevel.fromInt(logLevel);
32+
33+
switch (level) {
34+
case OFF: //LogLevel off
3535
break;
36-
case LogLevel.TRACE:
36+
case TRACE:
3737
log.trace(message);
3838
break;
39-
case LogLevel.DEBUG:
40-
log.debug(message);
41-
break;
42-
case LogLevel.INFO:
39+
case INFO:
4340
log.info(message);
4441
break;
45-
case LogLevel.WARNING:
42+
case WARN:
4643
log.warn(message);
4744
break;
48-
case LogLevel.ERROR:
45+
case ERROR:
4946
log.error(message);
5047
break;
51-
case LogLevel.FATAL:
48+
case FATAL:
5249
log.fatal(message);
5350
break;
5451
default:
55-
log.debug(message);
56-
}
52+
log.debug(message);
53+
}
5754
}
58-
55+
5956
public static void write(String message) {
6057
getLogger().debug(message);
6158
}
62-
59+
6360
public static void write(String message, String topic) {
6461
getLogger(topic).debug(message);
6562
}
66-
63+
6764
public static void error(String message) {
6865
getLogger().error(message);
6966
}
@@ -87,7 +84,7 @@ public static void fatal(String message, String topic) {
8784
public static void fatal(String message, String topic, Throwable ex) {
8885
getLogger(topic).fatal(message, ex);
8986
}
90-
87+
9188
public static void warning(String message) {
9289
getLogger().warn(message);
9390
}
@@ -115,7 +112,7 @@ public static void debug(String message) {
115112
public static void debug(String message, String topic) {
116113
getLogger(topic).debug(message);
117114
}
118-
115+
119116
public static void debug(String message, String topic, Throwable ex) {
120117
getLogger(topic).debug(message, ex);
121118
}
Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,24 @@
11
package com.genexus.diagnostics;
22

3-
public class LogLevel {
4-
5-
static final int OFF = 0;
6-
static final int TRACE = 1;
7-
static final int DEBUG = 5;
8-
static final int INFO = 10;
9-
static final int WARNING = 15;
10-
static final int ERROR = 20;
11-
static final int FATAL = 30;
12-
13-
3+
public enum LogLevel {
4+
OFF(0),
5+
TRACE(1),
6+
DEBUG(5),
7+
INFO(10),
8+
WARN(15),
9+
ERROR(20),
10+
FATAL(30);
11+
12+
private final int lvl;
13+
LogLevel(int lvl) { this.lvl = lvl; }
14+
public int intValue() { return lvl; }
15+
16+
public static LogLevel fromInt(int lvl) {
17+
for (LogLevel level : LogLevel.values()) {
18+
if (level.intValue() == lvl) {
19+
return level;
20+
}
21+
}
22+
return LogLevel.OFF;
23+
}
1424
}

common/src/main/java/com/genexus/diagnostics/UserLog.java

Lines changed: 58 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,37 +19,34 @@ public static ILogger getMainLogger() {
1919
private static ILogger getLogger(String topic) {
2020
ILogger log;
2121
if (topic != null && topic.length() > 0) {
22-
String loggerName = topic.startsWith("$") ? topic.substring(1): String.format("%s.%s", defaultUserLogNamespace, topic.trim());
22+
String loggerName = topic.startsWith("$") ? topic.substring(1) : String.format("%s.%s", defaultUserLogNamespace, topic.trim());
2323
log = LogManager.getLogger(loggerName);
24-
}
25-
else {
24+
} else {
2625
log = getMainLogger();
2726
}
2827
return log;
2928
}
3029

31-
public static void write( int logLevel, String message, String topic) {
30+
public static void write(int logLevel, String message, String topic) {
3231
ILogger log = getLogger(topic);
32+
LogLevel level = LogLevel.fromInt(logLevel);
3333

34-
switch (logLevel) {
35-
case LogLevel.OFF: //LogLevel off
34+
switch (level) {
35+
case OFF: //LogLevel off
3636
break;
37-
case LogLevel.TRACE:
37+
case TRACE:
3838
log.trace(message);
3939
break;
40-
case LogLevel.DEBUG:
41-
log.debug(message);
42-
break;
43-
case LogLevel.INFO:
40+
case INFO:
4441
log.info(message);
4542
break;
46-
case LogLevel.WARNING:
43+
case WARN:
4744
log.warn(message);
4845
break;
49-
case LogLevel.ERROR:
46+
case ERROR:
5047
log.error(message);
5148
break;
52-
case LogLevel.FATAL:
49+
case FATAL:
5350
log.fatal(message);
5451
break;
5552
default:
@@ -120,4 +117,51 @@ public static void debug(String message, String topic) {
120117
public static void debug(String message, String topic, Throwable ex) {
121118
getLogger(topic).debug(message, ex);
122119
}
120+
121+
public static void setContext(String key, Object value) {
122+
// Topic is ignored, also if you put something
123+
getLogger("$").setContext(key, value);
124+
}
125+
126+
public static void write(String message, String topic, int logLevel, Object data, boolean stackTrace) {
127+
getLogger(topic).write(message, logLevel, data, stackTrace);
128+
}
129+
130+
public static void write(String message, String topic, int logLevel, Object data) {
131+
write(message, topic, logLevel, data, false);
132+
}
133+
134+
public static boolean isDebugEnabled() {
135+
return getLogger().isDebugEnabled();
136+
}
137+
138+
public static boolean isErrorEnabled() {
139+
return getLogger().isErrorEnabled();
140+
}
141+
142+
public static boolean isFatalEnabled() {
143+
return getLogger().isFatalEnabled();
144+
}
145+
146+
public static boolean isInfoEnabled() {
147+
return getLogger().isInfoEnabled();
148+
}
149+
150+
public static boolean isWarnEnabled() {
151+
return getLogger().isWarnEnabled();
152+
}
153+
154+
public static boolean isTraceEnabled() {
155+
return getLogger().isTraceEnabled();
156+
}
157+
158+
public static boolean isEnabled(int logLevel) {
159+
return getLogger().isEnabled(logLevel);
160+
}
161+
162+
public static boolean isEnabled(int logLevel, String topic) {
163+
return getLogger(topic).isEnabled(logLevel);
164+
}
165+
166+
123167
}
Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,37 @@
11
package com.genexus.diagnostics.core;
22

33
public interface ILogger {
4-
4+
55
void fatal(String msg, Throwable ex);
66

77
void fatal(String msg1, String msg2, Throwable ex);
88

99
void fatal(Throwable ex, String[] list);
1010

1111
void fatal(String[] list);
12-
12+
1313
void fatal(String msg);
14-
14+
1515
void error(String msg, Throwable ex);
1616

1717
void error(String msg1, String msg2, Throwable ex);
1818

1919
void error(Throwable ex, String[] list);
2020

2121
void error(String[] list);
22-
22+
2323
void error(String msg);
2424

2525
void warn(String msg);
26-
26+
2727
void warn(Throwable ex, String[] list);
2828

2929
void warn(String[] list);
3030

3131
void warn(String msg, Throwable ex);
3232

3333
void debug(String msg);
34-
34+
3535
void debug(Throwable ex, String[] list);
3636

3737
void debug(String[] list);
@@ -41,19 +41,19 @@ public interface ILogger {
4141
void debug(String msg, Throwable ex);
4242

4343
void info(String[] list);
44-
44+
4545
void info(String msg);
4646

4747
void trace(String msg);
48-
48+
4949
void trace(Throwable ex, String[] list);
5050

5151
void trace(String[] list);
5252

5353
void trace(String msg1, String msg2, Throwable ex);
5454

5555
void trace(String msg, Throwable ex);
56-
56+
5757
boolean isDebugEnabled();
5858

5959
boolean isErrorEnabled();
@@ -65,5 +65,18 @@ public interface ILogger {
6565
* msg); } }
6666
*/
6767

68-
68+
default void setContext(String key, Object value) {}
69+
70+
default void write(String message, int logLevel, Object data, boolean stackTrace) {}
71+
72+
default boolean isFatalEnabled() { return false; }
73+
74+
default boolean isWarnEnabled() { return false; }
75+
76+
default boolean isInfoEnabled() { return false; }
77+
78+
default boolean isTraceEnabled() { return false; }
79+
80+
default boolean isEnabled(int logLevel) { return false; }
81+
6982
}

wrappercommon/pom.xml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,13 @@
3333
<groupId>org.apache.ws.security</groupId>
3434
<artifactId>wss4j</artifactId>
3535
<version>1.6.19</version>
36-
</dependency>
37-
</dependencies>
36+
</dependency>
37+
<dependency>
38+
<groupId>org.apache.logging.log4j</groupId>
39+
<artifactId>log4j-layout-template-json</artifactId>
40+
<version>2.24.3</version>
41+
</dependency>
42+
</dependencies>
3843

3944
<build>
4045
<finalName>gxwrappercommon</finalName>
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package com.genexus.diagnostics.core.provider;
2+
3+
import org.apache.logging.log4j.core.config.plugins.Plugin;
4+
import org.apache.logging.log4j.core.config.plugins.PluginFactory;
5+
import org.apache.logging.log4j.layout.template.json.resolver.EventResolverContext;
6+
import org.apache.logging.log4j.layout.template.json.resolver.EventResolverFactory;
7+
import org.apache.logging.log4j.layout.template.json.resolver.TemplateResolverConfig;
8+
import org.apache.logging.log4j.layout.template.json.resolver.TemplateResolverFactory;
9+
10+
11+
@Plugin(name = "CustomMessage", category = TemplateResolverFactory.CATEGORY)
12+
public final class CustomMessageFactory implements EventResolverFactory {
13+
private static final CustomMessageFactory INSTANCE = new CustomMessageFactory();
14+
private CustomMessageFactory() { /* no instances */ }
15+
16+
@PluginFactory
17+
public static CustomMessageFactory getInstance() {
18+
return INSTANCE;
19+
}
20+
21+
@Override
22+
public String getName() {
23+
return CustomMessageResolver.getName();
24+
}
25+
26+
@Override
27+
public CustomMessageResolver create(EventResolverContext context, TemplateResolverConfig config) {
28+
return new CustomMessageResolver(config);
29+
}
30+
}

0 commit comments

Comments
 (0)