Skip to content

Commit 7dd4dbd

Browse files
committed
Add logging settings to StatusLogger
1 parent 3650e58 commit 7dd4dbd

10 files changed

Lines changed: 166 additions & 22 deletions

File tree

dd-java-agent/agent-logging/agent-logging.gradle

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ apply from: "$rootDir/gradle/java.gradle"
22

33
excludedClassesCoverage += [
44
// Contains no code
5+
'datadog.trace.logging.simplelogger.SLCompatSettings.Names',
56
'datadog.trace.logging.simplelogger.SLCompatSettings.Keys',
67
'datadog.trace.logging.simplelogger.SLCompatSettings.Defaults',
78
// Can't test fallback path
@@ -16,6 +17,7 @@ excludedClassesCoverage += [
1617
]
1718

1819
dependencies {
19-
compile group: 'org.slf4j', name: 'slf4j-api', version: versions.slf4j
2020
// This is fine since this project is shadowed into the agent-jar by dd-java-agent:agent-bootstrap
21+
compile group: 'org.slf4j', name: 'slf4j-api', version: versions.slf4j
22+
compile project(':internal-api')
2123
}

dd-java-agent/agent-logging/src/main/java/datadog/trace/logging/LoggerHelperFactory.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package datadog.trace.logging;
22

3+
import java.util.Map;
4+
35
/** A factory for creating {@link LoggerHelper} instances. */
46
public abstract class LoggerHelperFactory {
57
/**
@@ -9,4 +11,11 @@ public abstract class LoggerHelperFactory {
911
* @return the {@link LoggerHelper} for the given name
1012
*/
1113
public abstract LoggerHelper loggerHelperForName(String name);
14+
15+
/**
16+
* Return a map describing all the settings for this {@link LoggerHelperFactory}.
17+
*
18+
* @return a {@link Map} describing the settings for this {@link LoggerHelperFactory}
19+
*/
20+
public abstract Map<String, Object> getSettingsDescription();
1221
}

dd-java-agent/agent-logging/src/main/java/datadog/trace/logging/ddlogger/DDLoggerFactory.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import datadog.trace.logging.LogLevel;
44
import datadog.trace.logging.LogLevelSwitcher;
5+
import datadog.trace.logging.LoggingSettingsDescription;
56
import datadog.trace.logging.simplelogger.SLCompatFactory;
67
import org.slf4j.ILoggerFactory;
78
import org.slf4j.Logger;
@@ -24,6 +25,7 @@ private SwitchableLogLevelFactory getHelperFactory() {
2425
factory = helperFactory;
2526
if (factory == null) {
2627
factory = helperFactory = new SwitchableLogLevelFactory(new SLCompatFactory());
28+
LoggingSettingsDescription.setDescription(factory.getSettingsDescription());
2729
}
2830
}
2931
}

dd-java-agent/agent-logging/src/main/java/datadog/trace/logging/ddlogger/SwitchableLogLevelFactory.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import datadog.trace.logging.LogLevelSwitcher;
55
import datadog.trace.logging.LoggerHelper;
66
import datadog.trace.logging.LoggerHelperFactory;
7+
import java.util.Map;
78
import org.slf4j.Marker;
89

910
public final class SwitchableLogLevelFactory extends LoggerHelperFactory
@@ -53,4 +54,9 @@ public void log(LogLevel level, String message, Throwable t) {
5354
delegate.log(level, message, t);
5455
}
5556
}
57+
58+
@Override
59+
public Map<String, Object> getSettingsDescription() {
60+
return delegate.getSettingsDescription();
61+
}
5662
}

dd-java-agent/agent-logging/src/main/java/datadog/trace/logging/simplelogger/SLCompatFactory.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import datadog.trace.logging.LoggerHelper;
44
import datadog.trace.logging.LoggerHelperFactory;
5+
import java.util.Map;
56
import java.util.Properties;
67

78
/**
@@ -57,4 +58,9 @@ public LoggerHelper loggerHelperForName(String name) {
5758
SLCompatSettings settings = getSettings();
5859
return new SLCompatHelper(name, settings);
5960
}
61+
62+
@Override
63+
public Map<String, Object> getSettingsDescription() {
64+
return getSettings().getSettingsDescription();
65+
}
6066
}

dd-java-agent/agent-logging/src/main/java/datadog/trace/logging/simplelogger/SLCompatSettings.java

Lines changed: 52 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,31 +13,47 @@
1313
import java.text.DateFormat;
1414
import java.text.SimpleDateFormat;
1515
import java.util.Date;
16+
import java.util.HashMap;
17+
import java.util.Map;
1618
import java.util.Properties;
1719

1820
/** Settings that provide the same configurable options as {@code SimpleLogger} from SLF4J. */
1921
public class SLCompatSettings {
2022

23+
public static final class Names {
24+
public static final String WARN_LEVEL_STRING = "warnLevelString";
25+
public static final String LEVEL_IN_BRACKETS = "levelInBrackets";
26+
public static final String LOG_FILE = "logFile";
27+
public static final String SHOW_SHORT_LOG_NAME = "showShortLogName";
28+
public static final String SHOW_LOG_NAME = "showLogName";
29+
public static final String SHOW_THREAD_NAME = "showThreadName";
30+
public static final String DATE_TIME_FORMAT = "dateTimeFormat";
31+
public static final String SHOW_DATE_TIME = "showDateTime";
32+
public static final String DEFAULT_LOG_LEVEL = "defaultLogLevel";
33+
public static final String EMBED_EXCEPTION = "embedException";
34+
public static final String CONFIGURATION_FILE = "configurationFile";
35+
}
36+
2137
public static final class Keys {
2238
// This is the package name that the shaded SimpleLogger had before. Use that for compatibility.
2339
private static final String PREFIX = "datadog.slf4j.simpleLogger.";
2440

2541
public static final String LOG_KEY_PREFIX = PREFIX + "log.";
2642
// This setting does not change anything in the behavior as of slf4j 1.7.30 so we ignore it
2743
// public static final String CACHE_OUTPUT_STREAM = PREFIX + "cacheOutputStream";
28-
public static final String WARN_LEVEL_STRING = PREFIX + "warnLevelString";
29-
public static final String LEVEL_IN_BRACKETS = PREFIX + "levelInBrackets";
30-
public static final String LOG_FILE = PREFIX + "logFile";
31-
public static final String SHOW_SHORT_LOG_NAME = PREFIX + "showShortLogName";
32-
public static final String SHOW_LOG_NAME = PREFIX + "showLogName";
33-
public static final String SHOW_THREAD_NAME = PREFIX + "showThreadName";
34-
public static final String DATE_TIME_FORMAT = PREFIX + "dateTimeFormat";
35-
public static final String SHOW_DATE_TIME = PREFIX + "showDateTime";
36-
public static final String DEFAULT_LOG_LEVEL = PREFIX + "defaultLogLevel";
37-
public static final String EMBED_EXCEPTION = PREFIX + "embedException";
44+
public static final String WARN_LEVEL_STRING = PREFIX + Names.WARN_LEVEL_STRING;
45+
public static final String LEVEL_IN_BRACKETS = PREFIX + Names.LEVEL_IN_BRACKETS;
46+
public static final String LOG_FILE = PREFIX + Names.LOG_FILE;
47+
public static final String SHOW_SHORT_LOG_NAME = PREFIX + Names.SHOW_SHORT_LOG_NAME;
48+
public static final String SHOW_LOG_NAME = PREFIX + Names.SHOW_LOG_NAME;
49+
public static final String SHOW_THREAD_NAME = PREFIX + Names.SHOW_THREAD_NAME;
50+
public static final String DATE_TIME_FORMAT = PREFIX + Names.DATE_TIME_FORMAT;
51+
public static final String SHOW_DATE_TIME = PREFIX + Names.SHOW_DATE_TIME;
52+
public static final String DEFAULT_LOG_LEVEL = PREFIX + Names.DEFAULT_LOG_LEVEL;
53+
public static final String EMBED_EXCEPTION = PREFIX + Names.EMBED_EXCEPTION;
3854

3955
// This is not available in SimpleLogger, but added here to simplify testing.
40-
static final String CONFIGURATION_FILE = PREFIX + "configurationFile";
56+
static final String CONFIGURATION_FILE = PREFIX + Names.CONFIGURATION_FILE;
4157
}
4258

4359
public static final class Defaults {
@@ -331,4 +347,29 @@ public String logNameForName(String name) {
331347
return "";
332348
}
333349
}
350+
351+
public Map<String, Object> getSettingsDescription() {
352+
Map<String, Object> settingsDescription = new HashMap<>();
353+
settingsDescription.put(
354+
Names.WARN_LEVEL_STRING,
355+
warnLevelString != null ? warnLevelString : LogLevel.WARN.toString());
356+
settingsDescription.put(Names.LEVEL_IN_BRACKETS, levelInBrackets);
357+
settingsDescription.put(
358+
Names.LOG_FILE, getString(properties, fileProperties, Keys.LOG_FILE, Defaults.LOG_FILE));
359+
settingsDescription.put(Names.SHOW_LOG_NAME, showLogName);
360+
settingsDescription.put(Names.SHOW_SHORT_LOG_NAME, showShortLogName);
361+
settingsDescription.put(Names.SHOW_THREAD_NAME, showThreadName);
362+
settingsDescription.put(Names.SHOW_DATE_TIME, showDateTime);
363+
String dateTimeFormat =
364+
getString(properties, fileProperties, Keys.DATE_TIME_FORMAT, Defaults.DATE_TIME_FORMAT);
365+
settingsDescription.put(
366+
Names.DATE_TIME_FORMAT, dateTimeFormat != null ? dateTimeFormat : "relative");
367+
settingsDescription.put(Names.DEFAULT_LOG_LEVEL, defaultLogLevel.toString());
368+
settingsDescription.put(Names.EMBED_EXCEPTION, embedException);
369+
settingsDescription.put(
370+
Names.CONFIGURATION_FILE,
371+
properties.getProperty(Keys.CONFIGURATION_FILE, Defaults.CONFIGURATION_FILE));
372+
373+
return settingsDescription;
374+
}
334375
}

dd-java-agent/agent-logging/src/test/groovy/datadog/trace/logging/ddlogger/DDLoggerTest.groovy

Lines changed: 47 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ import datadog.trace.logging.simplelogger.SLCompatFactory
77
import datadog.trace.logging.simplelogger.SLCompatSettings
88
import org.slf4j.Logger
99

10+
import static datadog.trace.logging.simplelogger.SLCompatSettings.Names
11+
import static datadog.trace.logging.simplelogger.SLCompatSettings.Keys
12+
import static datadog.trace.logging.simplelogger.SLCompatSettings.Defaults
13+
1014
class DDLoggerTest extends LogValidatingSpecification {
1115

1216
def marker = StaticMarkerBinder.getSingleton().markerFactory.getMarker("marker")
@@ -31,7 +35,7 @@ class DDLoggerTest extends LogValidatingSpecification {
3135
def "test enabled and log level switching"() {
3236
when:
3337
Properties props = new Properties()
34-
props.setProperty(SLCompatSettings.Keys.DEFAULT_LOG_LEVEL, level)
38+
props.setProperty(Keys.DEFAULT_LOG_LEVEL, level)
3539
def factory = new SwitchableLogLevelFactory(new SLCompatFactory(props))
3640
def logger = new DDLogger(factory, "foo.bar")
3741

@@ -77,8 +81,8 @@ class DDLoggerTest extends LogValidatingSpecification {
7781
def "test logging"() {
7882
when:
7983
Properties props = new Properties()
80-
props.setProperty(SLCompatSettings.Keys.DEFAULT_LOG_LEVEL, level)
81-
props.setProperty(SLCompatSettings.Keys.SHOW_THREAD_NAME, "false")
84+
props.setProperty(Keys.DEFAULT_LOG_LEVEL, level)
85+
props.setProperty(Keys.SHOW_THREAD_NAME, "false")
8286
def validator = createValidator("foo.bar")
8387
def printStream = new PrintStream(validator.outputStream, true)
8488
def settings = new SLCompatSettings(props, null, printStream)
@@ -211,8 +215,8 @@ class DDLoggerTest extends LogValidatingSpecification {
211215
def "test logging with an embedded exception in the message"() {
212216
setup:
213217
Properties props = new Properties()
214-
props.setProperty(SLCompatSettings.Keys.DEFAULT_LOG_LEVEL, "$level")
215-
props.setProperty(SLCompatSettings.Keys.EMBED_EXCEPTION, "true")
218+
props.setProperty(Keys.DEFAULT_LOG_LEVEL, "$level")
219+
props.setProperty(Keys.EMBED_EXCEPTION, "true")
216220
def outputStream = new ByteArrayOutputStream()
217221
def printStream = new PrintStream(outputStream, true)
218222
def settings = new SLCompatSettings(props, null, printStream)
@@ -254,8 +258,8 @@ class DDLoggerTest extends LogValidatingSpecification {
254258
def "test logging with an embedded exception in the message and varargs"() {
255259
setup:
256260
Properties props = new Properties()
257-
props.setProperty(SLCompatSettings.Keys.DEFAULT_LOG_LEVEL, "$level")
258-
props.setProperty(SLCompatSettings.Keys.EMBED_EXCEPTION, "true")
261+
props.setProperty(Keys.DEFAULT_LOG_LEVEL, "$level")
262+
props.setProperty(Keys.EMBED_EXCEPTION, "true")
259263
def outputStream = new ByteArrayOutputStream()
260264
def printStream = new PrintStream(outputStream, true)
261265
def settings = new SLCompatSettings(props, null, printStream)
@@ -305,9 +309,9 @@ class DDLoggerTest extends LogValidatingSpecification {
305309
def dir = File.createTempDir()
306310
def file = new File(dir, "log")
307311
def props = new Properties()
308-
props.setProperty(SLCompatSettings.Keys.DEFAULT_LOG_LEVEL, "DEBUG")
309-
props.setProperty(SLCompatSettings.Keys.SHOW_THREAD_NAME, "false")
310-
props.setProperty(SLCompatSettings.Keys.LOG_FILE, file.getAbsolutePath())
312+
props.setProperty(Keys.DEFAULT_LOG_LEVEL, "DEBUG")
313+
props.setProperty(Keys.SHOW_THREAD_NAME, "false")
314+
props.setProperty(Keys.LOG_FILE, file.getAbsolutePath())
311315
def settings = new SLCompatSettings(props)
312316
def factory = new SLCompatFactory(props)
313317
def logger = new DDLogger(factory, "bar.baz")
@@ -335,4 +339,37 @@ class DDLoggerTest extends LogValidatingSpecification {
335339
}
336340
dir.delete()
337341
}
342+
343+
def "test logger settings description"() {
344+
setup:
345+
def props = new Properties()
346+
props.setProperty(Keys.DEFAULT_LOG_LEVEL, level.toString())
347+
props.setProperty(Keys.SHOW_THREAD_NAME, "false")
348+
props.setProperty(Keys.SHOW_DATE_TIME, "true")
349+
if (warn) {
350+
props.setProperty(Keys.WARN_LEVEL_STRING, warn)
351+
}
352+
def settings = new SLCompatSettings(props)
353+
def factory = new SwitchableLogLevelFactory(new SLCompatFactory(props, settings))
354+
355+
expect:
356+
factory.settingsDescription == [
357+
(Names.WARN_LEVEL_STRING): expectedWarn,
358+
(Names.LEVEL_IN_BRACKETS): Defaults.LEVEL_IN_BRACKETS,
359+
(Names.LOG_FILE): Defaults.LOG_FILE,
360+
(Names.SHOW_LOG_NAME): Defaults.SHOW_LOG_NAME,
361+
(Names.SHOW_SHORT_LOG_NAME): Defaults.SHOW_SHORT_LOG_NAME,
362+
(Names.SHOW_THREAD_NAME): false,
363+
(Names.SHOW_DATE_TIME): true,
364+
(Names.DATE_TIME_FORMAT): "relative",
365+
(Names.DEFAULT_LOG_LEVEL): expectedLevel,
366+
(Names.EMBED_EXCEPTION): Defaults.EMBED_EXCEPTION,
367+
(Names.CONFIGURATION_FILE): Defaults.CONFIGURATION_FILE,
368+
]
369+
370+
where:
371+
level | warn | expectedLevel | expectedWarn
372+
LogLevel.TRACE | null | "TRACE" | "WARN"
373+
LogLevel.ERROR | "WRN" | "ERROR" | "WRN"
374+
}
338375
}

dd-trace-core/src/main/java/datadog/trace/core/StatusLogger.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import com.squareup.moshi.Types;
88
import datadog.trace.api.Config;
99
import datadog.trace.api.DDTraceApiInfo;
10+
import datadog.trace.logging.LoggingSettingsDescription;
1011
import java.io.IOException;
1112
import java.lang.annotation.Annotation;
1213
import java.lang.reflect.Type;
@@ -123,6 +124,8 @@ public void toJson(JsonWriter writer, Config config) throws IOException {
123124
writer.value(config.getConfigFile());
124125
writer.name("runtime_id");
125126
writer.value(config.getRuntimeId());
127+
writer.name("logging_settings");
128+
writeObjectMap(writer, LoggingSettingsDescription.getDescription());
126129
writer.endObject();
127130
}
128131
}
@@ -135,4 +138,21 @@ private static void writeMap(JsonWriter writer, Map<String, String> map) throws
135138
}
136139
writer.endObject();
137140
}
141+
142+
private static void writeObjectMap(JsonWriter writer, Map<String, Object> map)
143+
throws IOException {
144+
writer.beginObject();
145+
for (Map.Entry<String, Object> entry : map.entrySet()) {
146+
writer.name(entry.getKey());
147+
Object value = entry.getValue();
148+
if (value instanceof Number) {
149+
writer.value((Number) value);
150+
} else if (value instanceof Boolean) {
151+
writer.value((Boolean) value);
152+
} else {
153+
writer.value(String.valueOf(value));
154+
}
155+
}
156+
writer.endObject();
157+
}
138158
}

internal-api/internal-api.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ excludedClassesCoverage += [
1818
"datadog.trace.bootstrap.instrumentation.api.AgentTracer.NoopAgentTrace",
1919
"datadog.trace.bootstrap.instrumentation.api.ScopeSource",
2020
"datadog.trace.bootstrap.instrumentation.api.InternalSpanTypes",
21+
"datadog.trace.logging.LoggingSettingsDescription",
2122
"datadog.trace.util.AgentTaskScheduler",
2223
"datadog.trace.util.AgentTaskScheduler.PeriodicTask",
2324
"datadog.trace.util.AgentTaskScheduler.ShutdownHook",
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package datadog.trace.logging;
2+
3+
import java.util.Collections;
4+
import java.util.HashMap;
5+
import java.util.Map;
6+
7+
public final class LoggingSettingsDescription {
8+
private LoggingSettingsDescription() {}
9+
10+
private static volatile Map<String, Object> description = Collections.emptyMap();
11+
12+
public static void setDescription(Map<String, Object> description) {
13+
LoggingSettingsDescription.description =
14+
Collections.unmodifiableMap(new HashMap<>(description));
15+
}
16+
17+
public static Map<String, Object> getDescription() {
18+
return description;
19+
}
20+
}

0 commit comments

Comments
 (0)