Skip to content

Commit

Permalink
Re #123: Refactored Label into LabelBase + Label to use in the future…
Browse files Browse the repository at this point in the history
… for other tags with same behavior. Added tests.
  • Loading branch information
tkowalcz committed Jul 26, 2024
1 parent 00e5a74 commit 98c3fa0
Show file tree
Hide file tree
Showing 10 changed files with 173 additions and 73 deletions.
Original file line number Diff line number Diff line change
@@ -1,30 +1,16 @@
package pl.tkowalcz.tjahzi.log4j2.labels;

import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.config.Node;
import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
import org.apache.logging.log4j.core.config.plugins.PluginFactory;
import org.apache.logging.log4j.core.config.plugins.PluginValue;
import org.apache.logging.log4j.status.StatusLogger;

import java.util.regex.Pattern;

@Plugin(name = "label", category = Node.CATEGORY, printObject = true)
public class Label {

private static final Logger LOGGER = StatusLogger.getLogger();

private static final Pattern LABEL_NAME_PATTER = Pattern.compile("[a-zA-Z_][a-zA-Z0-9_]*");

private final String name;
private final String value;
private final String pattern;
public class Label extends LabelBase {

private Label(String name, String value, String pattern) {
this.name = name;
this.value = value;
this.pattern = pattern;
Label(String name, String value, String pattern) {
super(name, value, pattern);
}

@PluginFactory
Expand All @@ -33,43 +19,15 @@ public static Label createLabel(
@PluginValue("value") String value,
@PluginValue("pattern") String pattern
) {
if (name == null) {
LOGGER.error("Property name cannot be null");
}

if (pattern == null && value == null) {
LOGGER.error("Property must have pattern or value specified");
}

return new Label(name, value, pattern);
}

public boolean hasValidName() {
return hasValidName(getName());
}

public String getName() {
return name;
}

public String getPattern() {
return pattern;
}

public String getValue() {
return value;
}

public static boolean hasValidName(String label) {
return LABEL_NAME_PATTER.matcher(label).matches();
}

@Override
public String toString() {
return "Label{" +
"name='" + name + '\'' +
", pattern='" + pattern + '\'' +
", value='" + value + '\'' +
'}';
"name='" + getName() + '\'' +
", pattern='" + getPattern() + '\'' +
", value='" + getValue() + '\'' +
'}';
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package pl.tkowalcz.tjahzi.log4j2.labels;

import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.status.StatusLogger;

import java.util.regex.Pattern;

public abstract class LabelBase {

private static final Logger LOGGER = StatusLogger.getLogger();

private static final Pattern LABEL_NAME_PATTER = Pattern.compile("[a-zA-Z_][a-zA-Z0-9_]*");

private final String name;
private final String value;
private final String pattern;

LabelBase(String name, String value, String pattern) {
this.name = name;
this.value = value;
this.pattern = pattern;

if (name == null) {
LOGGER.error("Property name cannot be null");
}

if (pattern == null && value == null) {
LOGGER.error("Property must have pattern or value specified");
}
}

public boolean hasValidName() {
return hasValidName(getName());
}

public String getName() {
return name;
}

public String getPattern() {
return pattern;
}

public String getValue() {
return value;
}

public static boolean hasValidName(String label) {
return LABEL_NAME_PATTER.matcher(label).matches();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@ public class LabelFactory {
private static final Logger LOGGER = StatusLogger.getLogger();

private final String logLevelLabel;
private final Label[] labels;
private final LabelBase[] labels;

private final PatternParser patternParser;

public LabelFactory(Configuration configuration, String logLevelLabel, Label... labels) {
public LabelFactory(Configuration configuration, String logLevelLabel, LabelBase... labels) {
this.logLevelLabel = logLevelLabel;
this.labels = labels;

Expand Down Expand Up @@ -68,7 +68,7 @@ public LabelsDescriptor convertLabelsDroppingInvalid() {

private void detectAndLogDuplicateLabels() {
List<String> duplicatedLabels = stream(labels)
.collect(Collectors.groupingBy(Label::getName, counting()))
.collect(Collectors.groupingBy(LabelBase::getName, counting()))
.entrySet()
.stream()
.filter(entry -> entry.getValue() > 1)
Expand Down Expand Up @@ -101,13 +101,13 @@ private Map<String, LabelPrinter> convertAndLogViolations() {
}
)
.collect(toMap(
Label::getName,
LabelBase::getName,
this::toLabelOrLog4jPattern,
(original, duplicate) -> duplicate)
);
}

private LabelPrinter toLabelOrLog4jPattern(Label label) {
private LabelPrinter toLabelOrLog4jPattern(LabelBase label) {
if (label.getPattern() != null) {
return Log4jAdapterLabelPrinter.of(patternParser.parse(label.getPattern()));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ public class LabelPrinterFactory {

private static final Pattern CONTEXT_PATTERN = Pattern.compile("\\$\\{ctx:([^}:]+)(?::-([^}]+))?}");

public static LabelPrinter parse(Label label) {
public static LabelPrinter parse(LabelBase label) {
return parse(label.getValue());
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package pl.tkowalcz.tjahzi.log4j2.labels;

import java.util.HashMap;
import java.util.Map;

public class LabelsDescriptor {
Expand Down Expand Up @@ -30,5 +31,11 @@ public Map<String, String> getStaticLabels() {
public Map<String, LabelPrinter> getDynamicLabels() {
return dynamicLabels;
}
}

public Map<String, LabelPrinter> getAllLabels() {
Map<String, LabelPrinter> labels = new HashMap<>(dynamicLabels);
staticLabels.forEach((name, value) -> labels.put(name, Literal.of(value)));

return labels;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@

import org.apache.logging.log4j.core.LogEvent;

import java.util.Objects;
import java.util.function.Consumer;

public class Literal implements LabelPrinter {

private final String contents;

public Literal(String contents) {
private Literal(String contents) {
this.contents = contents;
}

Expand All @@ -25,4 +26,19 @@ public static Literal of(String string) {
public void append(LogEvent event, Consumer<CharSequence> appendable) {
appendable.accept(contents);
}

@Override
public final boolean equals(Object other) {
if (other instanceof Literal) {
Literal that = (Literal) other;
return Objects.equals(that.contents, contents);
}

return false;
}

@Override
public int hashCode() {
return Objects.hashCode(contents);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import org.apache.logging.log4j.core.LogEvent;

import java.util.Objects;
import java.util.function.Consumer;

public class MDCLookup implements LabelPrinter {
Expand All @@ -27,4 +28,20 @@ public void append(LogEvent event, Consumer<CharSequence> appendable) {
appendable.accept(defaultValue);
}
}

@Override
public final boolean equals(Object other) {
if (other instanceof MDCLookup) {
MDCLookup that = (MDCLookup) other;
return Objects.equals(this.variableName, that.variableName)
&& Objects.equals(this.defaultValue, that.defaultValue);
}

return false;
}

@Override
public int hashCode() {
return Objects.hash(variableName, defaultValue);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package pl.tkowalcz.tjahzi.log4j2.labels;

import org.junit.jupiter.api.Test;

import static org.assertj.core.api.Assertions.assertThat;

abstract class LabelBaseTest {

public abstract LabelBase createCUT(String name, String value, String pattern);

@Test
void shouldValidateNamePattern() {
// Given
LabelBase correctLabel = createCUT("aaa_bbb_ccc", "fobar", null);
LabelBase tooShortLabel = createCUT("", "foobar", null);
LabelBase labelWithInvalidChars = createCUT("log-level", "foobar", null);

// When & Then
assertThat(correctLabel.hasValidName()).isTrue();
assertThat(tooShortLabel.hasValidName()).isFalse();
assertThat(labelWithInvalidChars.hasValidName()).isFalse();
}
}
Original file line number Diff line number Diff line change
@@ -1,21 +1,9 @@
package pl.tkowalcz.tjahzi.log4j2.labels;

import org.junit.jupiter.api.Test;
class LabelTest extends LabelBaseTest {

import static org.assertj.core.api.Assertions.assertThat;

class LabelTest {

@Test
void shouldValidateNamePattern() {
// Given
Label correctLabel = Label.createLabel("aaa_bbb_ccc", "fobar", null);
Label tooShortLabel = Label.createLabel("", "foobar", null);
Label labelWithInvalidChars = Label.createLabel("log-level", "foobar", null);

// When & Then
assertThat(correctLabel.hasValidName()).isTrue();
assertThat(tooShortLabel.hasValidName()).isFalse();
assertThat(labelWithInvalidChars.hasValidName()).isFalse();
@Override
public LabelBase createCUT(String name, String value, String pattern) {
return Label.createLabel(name, value, pattern);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package pl.tkowalcz.tjahzi.log4j2.labels;

import org.junit.jupiter.api.Test;

import java.util.Map;

import static org.assertj.core.api.Assertions.assertThat;

class LabelsDescriptorTest {

@Test
void shouldCombineDynamicAndStaticLabels() {
// Given
Map<String, String> actualStaticLabels = Map.of("foo", "bar", "123", "456");
Map<String, LabelPrinter> actualDynamicLabels = Map.of(
"stuff", MDCLookup.of("zzz", "yyy")
);

LabelsDescriptor descriptor = new LabelsDescriptor(
"level",
actualStaticLabels,
actualDynamicLabels
);

// When
Map<String, String> staticLabels = descriptor.getStaticLabels();
Map<String, LabelPrinter> dynamicLabels = descriptor.getDynamicLabels();
Map<String, LabelPrinter> allLabels = descriptor.getAllLabels();

// Then
assertThat(staticLabels).isEqualTo(actualStaticLabels);
assertThat(dynamicLabels).isEqualTo(actualDynamicLabels);
assertThat(allLabels)
.containsExactlyInAnyOrderEntriesOf(Map.<String, LabelPrinter>of(
"foo", Literal.of("bar"),
"123", Literal.of("456"),
"stuff", MDCLookup.of("zzz", "yyy")
));
}
}

0 comments on commit 98c3fa0

Please sign in to comment.