Created
September 27, 2012 13:14
-
-
Save chrsan/3793920 to your computer and use it in GitHub Desktop.
A logback discriminator for the akkaSource MDC value.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package se.fishtank; | |
import java.net.URI; | |
import java.util.Map; | |
import ch.qos.logback.classic.spi.ILoggingEvent; | |
import ch.qos.logback.core.sift.Discriminator; | |
import ch.qos.logback.core.spi.ContextAwareBase; | |
public class AkkaSourceDiscriminator extends ContextAwareBase implements Discriminator<ILoggingEvent> { | |
private String key; | |
private String defaultValue; | |
private String actorPathContains; | |
private boolean onlyUseActorName = true; | |
private boolean started = false; | |
@Override | |
public String getDiscriminatingValue(ILoggingEvent event) { | |
Map<String, String> mdc = event.getMDCPropertyMap(); | |
if (mdc == null) return defaultValue; | |
String value = mdc.get("akkaSource"); | |
if (value == null || !value.contains(actorPathContains)) return defaultValue; | |
String path = getPath(value); | |
if (path == null || "/".equals(path)) return defaultValue; | |
if (onlyUseActorName) { | |
int idx = path.lastIndexOf('/'); | |
if (idx == -1) return defaultValue; | |
return path.substring(idx + 1); | |
} else { | |
if (path.charAt(0) == '/') | |
path = path.substring(1); | |
return path.replace('/', '-'); | |
} | |
} | |
@Override | |
public String getKey() { | |
return key; | |
} | |
public void setKey(String key) { | |
this.key = key; | |
} | |
public void setDefaultValue(String defaultValue) { | |
this.defaultValue = defaultValue; | |
} | |
public void setActorPathContains(String actorPathContains) { | |
this.actorPathContains = actorPathContains; | |
} | |
public void setOnlyUseActorName(String value) { | |
if (value != null) { | |
if ("true".equals(value)) { | |
onlyUseActorName = true; | |
} else if ("false".equals(value)) { | |
onlyUseActorName = false; | |
} else { | |
throw new IllegalArgumentException("Expected \"true\" or \"false\" for property \"OnlyUseActorName\""); | |
} | |
} | |
} | |
@Override | |
public void start() { | |
started = isValid("Key", key) | |
&& isValid("DefaultValue", defaultValue) | |
&& isValid("ActorPathContains", actorPathContains); | |
} | |
@Override | |
public void stop() { | |
started = false; | |
} | |
@Override | |
public boolean isStarted() { | |
return started; | |
} | |
private String getPath(String akkaSource) { | |
try { | |
return new URI(akkaSource).getPath(); | |
} catch (Exception e) { | |
return null; | |
} | |
} | |
private boolean isValid(String property, String value) { | |
if (value == null || value.isEmpty()) { | |
addError("The \"" + property + "\" property must be set"); | |
return false; | |
} | |
return true; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<configuration scan="false" debug="false"> | |
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> | |
<encoder> | |
<pattern>%date{ISO8601} %-5level %logger{36} %X{akkaSource} %X{sourceThread} - %msg%n</pattern> | |
</encoder> | |
</appender> | |
<appender name="FILE_DEBUG" class="ch.qos.logback.core.FileAppender"> | |
<file>/tmp/debug.log</file> | |
<encoder> | |
<pattern>%date{ISO8601} %-5level %logger{36} %X{akkaSource} %X{sourceThread} - %msg%n</pattern> | |
</encoder> | |
</appender> | |
<appender name="SIFT_ACTOR1" class="ch.qos.logback.classic.sift.SiftingAppender"> | |
<discriminator class="se.fishtank.AkkaSourceDiscriminator"> | |
<key>actor</key> | |
<defaultValue>unknown</defaultValue> | |
<!-- What the actor path should contain to consider this a match. --> | |
<actorPathContains>actor1</actorPathContains> | |
<!-- Uncomment the stuff below to use the full actor path as the filename. --> | |
<!-- | |
<onlyUseActorName>false</onlyUseActorName> | |
--> | |
</discriminator> | |
<sift> | |
<appender name="FILE_ACTOR_${actor}" class="ch.qos.logback.core.FileAppender"> | |
<file>/tmp/${actor}.log</file> | |
<encoder> | |
<pattern>%date{ISO8601} %-5level %logger{36} %X{akkaSource} %X{sourceThread} - %msg%n</pattern> | |
</encoder> | |
</appender> | |
</sift> | |
</appender> | |
<root level="DEBUG"> | |
<appender-ref ref="STDOUT"/> | |
<appender-ref ref="FILE_DEBUG"/> | |
<appender-ref ref="SIFT_ACTOR1"/> | |
</root> | |
</configuration> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
When setting
<onlyUseActorName>false</onlyUseActorName>
the full actor path will be used as the filename prefix. I.e. if the path is/user/foo/bar
the filename prefix will beuser-foo-bar
.