001package io.prometheus.client.log4j2; 002 003import io.prometheus.client.Counter; 004import org.apache.logging.log4j.Level; 005import org.apache.logging.log4j.core.LogEvent; 006import org.apache.logging.log4j.core.appender.AbstractAppender; 007import org.apache.logging.log4j.core.config.plugins.Plugin; 008import org.apache.logging.log4j.core.config.plugins.PluginAttribute; 009import org.apache.logging.log4j.core.config.plugins.PluginFactory; 010 011import static org.apache.logging.log4j.Level.*; 012 013/** 014 * Log4j2 log statements at various log levels 015 * <p> 016 * Example log4j2 configuration: 017 * <pre> 018 * <?xml version="1.0" encoding="UTF-8"?> 019 * <Configuration packages="io.prometheus.client.log4j2"> 020 * <Appenders> 021 * <Prometheus name="PROMETHEUS"/> 022 * </Appenders> 023 * <Loggers> 024 * <Root level="trace"> 025 * <AppenderRef ref="PROMETHEUS"/> 026 * </Root> 027 * </Loggers> 028 * </Configuration> 029 * </pre> 030 * Example metrics being exported: 031 * <pre> 032 * log4j_appender_total{level="trace",} 1.0 033 * log4j_appender_total{level="debug",} 2.0 034 * log4j_appender_total{level="info",} 3.0 035 * log4j_appender_total{level="warn",} 4.0 036 * log4j_appender_total{level="error",} 5.0 037 * log4j_appender_total{level="fatal",} 6.0 038 * </pre> 039 */ 040@Plugin(name = "Prometheus", category = "Core", elementType = "appender") 041public final class InstrumentedAppender extends AbstractAppender { 042 043 public static final String COUNTER_NAME = "log4j2_appender_total"; 044 045 private static final Counter COUNTER; 046 private static final Counter.Child TRACE_LABEL; 047 private static final Counter.Child DEBUG_LABEL; 048 private static final Counter.Child INFO_LABEL; 049 private static final Counter.Child WARN_LABEL; 050 private static final Counter.Child ERROR_LABEL; 051 private static final Counter.Child FATAL_LABEL; 052 053 static { 054 COUNTER = Counter.build().name(COUNTER_NAME) 055 .help("Log4j2 log statements at various log levels") 056 .labelNames("level") 057 .register(); 058 059 TRACE_LABEL = COUNTER.labels("trace"); 060 DEBUG_LABEL = COUNTER.labels("debug"); 061 INFO_LABEL = COUNTER.labels("info"); 062 WARN_LABEL = COUNTER.labels("warn"); 063 ERROR_LABEL = COUNTER.labels("error"); 064 FATAL_LABEL = COUNTER.labels("fatal"); 065 } 066 067 /** 068 * Create a new instrumented appender using the default registry. 069 */ 070 protected InstrumentedAppender(String name) { 071 super(name, null, null); 072 } 073 074 @Override 075 public void append(LogEvent event) { 076 Level level = event.getLevel(); 077 if (TRACE.equals(level)) TRACE_LABEL.inc(); 078 else if (DEBUG.equals(level)) DEBUG_LABEL.inc(); 079 else if (INFO.equals(level)) INFO_LABEL.inc(); 080 else if (WARN.equals(level)) WARN_LABEL.inc(); 081 else if (ERROR.equals(level)) ERROR_LABEL.inc(); 082 else if (FATAL.equals(level)) FATAL_LABEL.inc(); 083 } 084 085 @PluginFactory 086 public static InstrumentedAppender createAppender( 087 @PluginAttribute("name") String name) { 088 if (name == null) { 089 LOGGER.error("No name provided for InstrumentedAppender"); 090 return null; 091 } 092 return new InstrumentedAppender(name); 093 } 094 095}