adds the logger_name and thread_name labels for logback (#108)

This commit is contained in:
Jean Helou authored and GitHub committed 2023-03-17 22:55:27 +01:00
1 parent 0e9d5222d2
commit 86eeab2a11
8 files changed
+231 -17

No files matched your search

@@ -17,15 +17,21 @@ public class LabelFactory {
private final ContextAware internalLogger;
private final String logLevelLabel;
private final String loggerNameLabel;
private final String threadNameLabel;
private final Label[] labels;
public LabelFactory(
ContextAware internalLogger,
String logLevelLabel,
String loggerNameLabel,
String threadNameLabel,
Label... labels
) {
this.internalLogger = internalLogger;
this.logLevelLabel = logLevelLabel;
this.loggerNameLabel = loggerNameLabel;
this.threadNameLabel = threadNameLabel;
this.labels = labels;
}
@@ -36,9 +42,34 @@ public class LabelFactory {
public String validateLogLevelLabel(HashMap<String, String> existingLabels) {
if (logLevelLabel != null) {
return validateLogLevelLabelAgainst(
return validatePredefinedLabelAgainst(
existingLabels,
logLevelLabel
logLevelLabel,
"log level label"
);
}
return null;
}
public String validateLoggerNameLabel(HashMap<String, String> existingLabels) {
if (loggerNameLabel != null) {
return validatePredefinedLabelAgainst(
existingLabels,
loggerNameLabel,
"logger name label"
);
}
return null;
}
public String validateThreadNameLabel(HashMap<String, String> existingLabels) {
if (threadNameLabel != null) {
return validatePredefinedLabelAgainst(
existingLabels,
threadNameLabel,
"thread name label"
);
}
@@ -89,15 +120,17 @@ public class LabelFactory {
return lokiLabels;
}
private String validateLogLevelLabelAgainst(
private String validatePredefinedLabelAgainst(
Map<String, String> existingLabels,
String logLevelLabel
String predefinedLabel,
String predefinedLabelDescription
) {
if (!Label.hasValidName(logLevelLabel)) {
if (!Label.hasValidName(predefinedLabel)) {
internalLogger.addWarn(
String.format(
"Ignoring log level label '%s' - contains invalid characters. %s\n",
logLevelLabel,
"Ignoring %s '%s' - contains invalid characters. %s\n",
predefinedLabelDescription,
predefinedLabel,
GitHubDocs.LABEL_NAMING.getLogMessage()
)
);
@@ -105,15 +138,16 @@ public class LabelFactory {
return null;
}
if (existingLabels.remove(logLevelLabel) != null) {
if (existingLabels.remove(predefinedLabel) != null) {
internalLogger.addWarn(
String.format(
"Ignoring log level label '%s' - conflicts with label defined in configuration.\n",
logLevelLabel
"Ignoring %s '%s' - conflicts with label defined in configuration.\n",
predefinedLabelDescription,
predefinedLabel
)
);
}
return logLevelLabel;
return predefinedLabel;
}
}
@@ -26,6 +26,8 @@ public class LokiAppender extends LokiAppenderConfigurator {
private TjahziLogger logger;
private String logLevelLabel;
private String loggerNameLabel;
private String threadNameLabel;
private List<String> mdcLogLabels;
private MutableMonitoringModuleWrapper monitoringModuleWrapper;
@@ -62,11 +64,15 @@ public class LokiAppender extends LokiAppenderConfigurator {
@Override
protected void append(ILoggingEvent event) {
String logLevel = event.getLevel().toString();
String loggerName = event.getLoggerName();
String threadName = event.getThreadName();
ByteBuffer logLine = actualEncoder.apply(event);
Map<String, String> mdcPropertyMap = event.getMDCPropertyMap();
LabelSerializer labelSerializer = LabelSerializers.threadLocal();
appendLogLabel(labelSerializer, logLevel);
appendLoggerLabel(labelSerializer, loggerName);
appendThreadLabel(labelSerializer, threadName);
appendMdcLogLabels(labelSerializer, mdcPropertyMap);
logger.log(
@@ -83,6 +89,17 @@ public class LokiAppender extends LokiAppenderConfigurator {
}
}
private void appendLoggerLabel(LabelSerializer labelSerializer, String loggerName) {
if (loggerNameLabel != null) {
labelSerializer.appendLabel(loggerNameLabel, loggerName);
}
}
private void appendThreadLabel(LabelSerializer labelSerializer, String threadName) {
if (threadNameLabel != null) {
labelSerializer.appendLabel(threadNameLabel, threadName);
}
}
@SuppressWarnings("ForLoopReplaceableByForEach") // Allocator goes brrrr
private void appendMdcLogLabels(LabelSerializer serializer,
Map<String, String> mdcPropertyMap) {
@@ -112,6 +129,8 @@ public class LokiAppender extends LokiAppenderConfigurator {
LokiAppenderFactory lokiAppenderFactory = new LokiAppenderFactory(this);
loggingSystem = lokiAppenderFactory.createAppender();
logLevelLabel = lokiAppenderFactory.getLogLevelLabel();
loggerNameLabel = lokiAppenderFactory.getLoggerNameLabel();
threadNameLabel = lokiAppenderFactory.getThreadNameLabel();
mdcLogLabels = lokiAppenderFactory.getMdcLogLabels();
monitoringModuleWrapper = lokiAppenderFactory.getMonitoringModuleWrapper();
@@ -32,6 +32,8 @@ public abstract class LokiAppenderConfigurator extends UnsynchronizedAppenderBas
private boolean useOffHeapBuffer = true;
private String logLevelLabel;
private String loggerNameLabel;
private String threadNameLabel;
private final List<String> mdcLogLabels = new ArrayList<>();
private long batchSize = 10_2400;
@@ -156,6 +158,22 @@ public abstract class LokiAppenderConfigurator extends UnsynchronizedAppenderBas
this.logLevelLabel = logLevelLabel;
}
public String getLoggerNameLabel() {
return loggerNameLabel;
}
public void setLoggerNameLabel(String loggerNameLabel) {
this.loggerNameLabel = loggerNameLabel;
}
public String getThreadNameLabel() {
return threadNameLabel;
}
public void setThreadNameLabel(String threadNameLabel) {
this.threadNameLabel = threadNameLabel;
}
public void setBatchSize(long batchSize) {
this.batchSize = batchSize;
}
@@ -20,6 +20,8 @@ public class LokiAppenderFactory {
private final HashMap<String, String> lokiLabels;
private final String logLevelLabel;
private final String loggerNameLabel;
private final String threadNameLabel;
private final List<String> mdcLogLabels;
private final MutableMonitoringModuleWrapper monitoringModuleWrapper;
@@ -29,11 +31,15 @@ public class LokiAppenderFactory {
LabelFactory labelFactory = new LabelFactory(
configurator,
configurator.getLogLevelLabel(),
configurator.getLoggerNameLabel(),
configurator.getThreadNameLabel(),
configurator.getLabels().toArray(new Label[0])
);
lokiLabels = labelFactory.convertLabelsDroppingInvalid();
logLevelLabel = labelFactory.validateLogLevelLabel(lokiLabels);
loggerNameLabel = labelFactory.validateLoggerNameLabel(lokiLabels);
threadNameLabel = labelFactory.validateThreadNameLabel(lokiLabels);
mdcLogLabels = configurator.getMdcLogLabels();
monitoringModuleWrapper = new MutableMonitoringModuleWrapper();
}
@@ -96,6 +102,14 @@ public class LokiAppenderFactory {
return logLevelLabel;
}
public String getLoggerNameLabel() {
return loggerNameLabel;
}
public String getThreadNameLabel() {
return threadNameLabel;
}
public MutableMonitoringModuleWrapper getMonitoringModuleWrapper() {
return monitoringModuleWrapper;
}
@@ -20,6 +20,8 @@ class LabelFactoryTest {
LabelFactory labelFactory = new LabelFactory(
new ConsoleAppender<>(),
"log_level",
"logger_name",
"thread_name",
thisIsADuplicateAndShouldBeDropped,
thisShouldStay,
thisTooShouldStay
@@ -45,6 +47,8 @@ class LabelFactoryTest {
LabelFactory labelFactory = new LabelFactory(
new ConsoleAppender<>(),
"log_level",
"logger_name",
"thread_name",
thisShouldStayToo,
thisShouldStay,
invalidNameShouldBeDropped
@@ -61,7 +65,7 @@ class LabelFactoryTest {
}
@Test
void shouldAcceptNullLogLevel() {
void shouldAcceptNullPredefinedLabels() {
// Given
Label label1 = Label.createLabel("ip", "10.0.2.34");
Label label2 = Label.createLabel("region", "coruscant-west-2");
@@ -69,6 +73,8 @@ class LabelFactoryTest {
LabelFactory labelFactory = new LabelFactory(
new ConsoleAppender<>(),
null,
null,
null,
label2,
label1
);
@@ -94,6 +100,8 @@ class LabelFactoryTest {
LabelFactory labelFactory = new LabelFactory(
new ConsoleAppender<>(),
logLevelLabel,
null,
null,
thisShouldBeRemovedDueToConflict,
thisShouldStay
);
@@ -121,7 +129,7 @@ class LabelFactoryTest {
// Given
String logLevelLabel = "log-level";
LabelFactory labelFactory = new LabelFactory(new ConsoleAppender<>(), logLevelLabel);
LabelFactory labelFactory = new LabelFactory(new ConsoleAppender<>(), logLevelLabel, null, null);
// When
String actual = labelFactory.validateLogLevelLabel(new HashMap<>());
@@ -131,10 +139,115 @@ class LabelFactoryTest {
}
@Test
void shouldHandleDisabledLogLevelLabel() {
void loggerNameLabelShouldOverrideConflictingLabel() {
// Given
String loggerNameLabel = "logger_name";
Label thisShouldStay = Label.createLabel("ip", "10.0.2.34");
Label thisShouldBeRemovedDueToConflict = Label.createLabel(loggerNameLabel, "coruscant-west-2");
LabelFactory labelFactory = new LabelFactory(
new ConsoleAppender<>(),
null,
loggerNameLabel,
null,
thisShouldBeRemovedDueToConflict,
thisShouldStay
);
HashMap<String, String> labels = new HashMap<>(
Map.ofEntries(
asEntry(thisShouldStay),
asEntry(thisShouldBeRemovedDueToConflict)
)
);
// When
String actual = labelFactory.validateLoggerNameLabel(labels);
// Then
assertThat(labels).containsOnly(
asEntry(thisShouldStay)
);
assertThat(actual).isEqualTo(loggerNameLabel);
}
@Test
void shouldDisableLoggerNameLabelIfItHasInvalidName() {
// Given
String loggerNameLabel = "logger-name";
LabelFactory labelFactory = new LabelFactory(new ConsoleAppender<>(), null, loggerNameLabel, null);
// When
String actual = labelFactory.validateLogLevelLabel(new HashMap<>());
// Then
assertThat(actual).isNull();
}
@Test
void threadNameLabelShouldOverrideConflictingLabel() {
// Given
String threadNameLabel = "thread_name";
Label thisShouldStay = Label.createLabel("ip", "10.0.2.34");
Label thisShouldBeRemovedDueToConflict = Label.createLabel(threadNameLabel, "coruscant-west-2");
LabelFactory labelFactory = new LabelFactory(
new ConsoleAppender<>(),
threadNameLabel,
null,
null,
thisShouldBeRemovedDueToConflict,
thisShouldStay
);
HashMap<String, String> labels = new HashMap<>(
Map.ofEntries(
asEntry(thisShouldStay),
asEntry(thisShouldBeRemovedDueToConflict)
)
);
// When
String actual = labelFactory.validateLogLevelLabel(labels);
// Then
assertThat(labels).containsOnly(
asEntry(thisShouldStay)
);
assertThat(actual).isEqualTo(threadNameLabel);
}
@Test
void shouldDisableThreadNameLabelIfItHasInvalidName() {
// Given
String threadNameLabel = "thread-name";
LabelFactory labelFactory = new LabelFactory(new ConsoleAppender<>(), threadNameLabel, null, null);
// When
String actual = labelFactory.validateLogLevelLabel(new HashMap<>());
// Then
assertThat(actual).isNull();
}
@Test
void shouldHandleDisabledPredefinedLabels() {
// Given
String logLevelLabel = null;
LabelFactory labelFactory = new LabelFactory(new ConsoleAppender<>(), logLevelLabel);
String loggerNameLabel = null;
String threadNameLabel = null;
LabelFactory labelFactory = new LabelFactory(
new ConsoleAppender<>(),
logLevelLabel,
loggerNameLabel,
threadNameLabel
);
// When
String actual = labelFactory.validateLogLevelLabel(new HashMap<>());
@@ -36,8 +36,11 @@ class LogLevelLabelConfigurationTest extends IntegrationTest {
LoggerContext context = loadConfig("appender-test-with-log-label-set.xml");
// When
String originalThreadName=Thread.currentThread().getName();
Thread.currentThread().setName("appender-test-with-log-label-set.xml");
Logger logger = context.getLogger(LogLevelLabelConfigurationTest.class);
logger.info("Test");
Thread.currentThread().setName(originalThreadName);
// Then
assertThat(loki)
@@ -46,6 +49,8 @@ class LogLevelLabelConfigurationTest extends IntegrationTest {
.body("status", equalTo("success"))
.body("data.result.size()", equalTo(1))
.body("data.result[0].stream.log_level", equalTo("INFO"))
.body("data.result[0].stream.logger_name", equalTo("pl.tkowalcz.tjahzi.logback.LogLevelLabelConfigurationTest"))
.body("data.result[0].stream.thread_name", equalTo("appender-test-with-log-label-set.xml"))
);
}
}
@@ -15,7 +15,12 @@
<logLevelLabel>
log_level
</logLevelLabel>
<loggerNameLabel>
logger_name
</loggerNameLabel>
<threadNameLabel>
thread_name
</threadNameLabel>
<label>
<name>test</name>
<value>shouldSendLogLevelAsConfigured</value>
@@ -18,6 +18,12 @@
<logLevelLabel>
log_level
</logLevelLabel>
<loggerNameLabel>
logger_name
</loggerNameLabel>
<threadNameLabel>
thread_name
</threadNameLabel>
</appender>
<root level="debug">