Markers¶
Markers allow you to tag log statements with special labels for filtering and routing purposes.
What are Markers?¶
Markers are named tags attached to log events that can be used to:
- Filter logs by category or type
- Route specific logs to different appenders
- Trigger alerts based on marker presence
- Add semantic meaning to log statements
Basic Usage¶
import io.hermes.Marker;
import io.hermes.MarkerFactory;
// Create markers
Marker securityMarker = MarkerFactory.getMarker("SECURITY");
Marker performanceMarker = MarkerFactory.getMarker("PERFORMANCE");
// Use markers in log statements
log.info(securityMarker, "User {} logged in", username);
log.warn(securityMarker, "Failed login attempt for {}", username);
log.debug(performanceMarker, "Query took {} ms", duration);
Hierarchical Markers¶
Markers can have parent markers for hierarchical organization:
Marker sqlMarker = MarkerFactory.getMarker("SQL");
Marker slowQueryMarker = MarkerFactory.getMarker("SLOW_QUERY");
slowQueryMarker.add(sqlMarker); // SLOW_QUERY is a child of SQL
// This log matches both SLOW_QUERY and SQL filters
log.warn(slowQueryMarker, "Query exceeded threshold: {} ms", duration);
Common Marker Patterns¶
Security Events¶
Marker SECURITY = MarkerFactory.getMarker("SECURITY");
Marker AUDIT = MarkerFactory.getMarker("AUDIT");
log.info(SECURITY, "Access granted to resource {} for user {}", resource, user);
log.warn(AUDIT, "Configuration changed by admin {}", adminId);
Performance Monitoring¶
Marker PERFORMANCE = MarkerFactory.getMarker("PERFORMANCE");
Marker SLOW_OPERATION = MarkerFactory.getMarker("SLOW_OPERATION");
if (duration > threshold) {
log.warn(SLOW_OPERATION, "Operation took {} ms", duration);
}
Business Events¶
Marker ORDER = MarkerFactory.getMarker("ORDER");
Marker PAYMENT = MarkerFactory.getMarker("PAYMENT");
log.info(ORDER, "Order {} created for customer {}", orderId, customerId);
log.info(PAYMENT, "Payment processed: amount={}, method={}", amount, method);
Filtering by Markers¶
Configure appenders to filter based on markers:
// Example: Send security logs to a separate file
FileAppender securityAppender = new FileAppender("security.log");
securityAppender.setMarkerFilter("SECURITY");
// Example: Send all logs except performance markers
ConsoleAppender console = new ConsoleAppender();
console.setExcludeMarker("PERFORMANCE");
Marker API¶
MarkerFactory¶
MarkerFactory.getMarker(String name)- Get or create a markerMarkerFactory.exists(String name)- Check if marker existsMarkerFactory.detachMarker(String name)- Remove marker from registry
Marker Methods¶
marker.getName()- Get marker namemarker.add(Marker child)- Add child markermarker.remove(Marker child)- Remove child markermarker.hasChildren()- Check if marker has childrenmarker.contains(Marker other)- Check if marker contains another (recursively)
Pattern Layout Integration¶
Include marker names in log output:
PatternLayout layout = new PatternLayout(
"%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %marker %logger - %msg%n"
);
Example output:
2024-01-10 10:30:45 [http-nio-8080-exec-1] INFO SECURITY com.example.AuthService - User alice logged in
2024-01-10 10:30:46 [http-nio-8080-exec-2] WARN SLOW_QUERY com.example.OrderService - Query exceeded threshold: 1500 ms
JSON Layout Integration¶
Markers appear as fields in JSON output:
{
"timestamp": "2024-01-10T10:30:45.123Z",
"level": "INFO",
"marker": "SECURITY",
"logger": "com.example.AuthService",
"message": "User alice logged in"
}
Best Practices¶
- Use consistent naming - Define markers as constants
- Document marker meanings - Create a marker registry for your team
- Don't overuse - Too many markers reduce their effectiveness
- Use hierarchies - Organize related markers with parent/child relationships
- Filter strategically - Route critical markers to dedicated appenders
- Combine with MDC - Use markers for category, MDC for context
Example: Comprehensive Marker Strategy¶
public class AppMarkers {
// Top-level categories
public static final Marker SECURITY = MarkerFactory.getMarker("SECURITY");
public static final Marker BUSINESS = MarkerFactory.getMarker("BUSINESS");
public static final Marker TECHNICAL = MarkerFactory.getMarker("TECHNICAL");
// Security subcategories
public static final Marker AUTH = MarkerFactory.getMarker("AUTH");
public static final Marker AUDIT = MarkerFactory.getMarker("AUDIT");
static {
AUTH.add(SECURITY);
AUDIT.add(SECURITY);
}
// Usage
public void login(String username) {
log.info(AUTH, "User {} logged in", username);
}
public void changeConfig(String setting, String value) {
log.info(AUDIT, "Config changed: {}={}", setting, value);
}
}
Use Cases¶
- Security monitoring: Tag authentication, authorization, and audit events
- Performance tracking: Mark slow operations, expensive queries
- Business metrics: Tag revenue events, user actions, conversions
- Alerting: Trigger alerts based on specific markers
- Compliance: Mark logs that require retention or special handling
- Debugging: Temporarily mark subsystem logs for focused troubleshooting