@AfterClass public static void resetLogback() throws Exception { new LogbackHelper().resetFromXml("/logback-test.xml"); }
public LoggerContext configure() { LoggerContext ctx = helper.getRootContext(); ctx.reset(); helper.enableJulChangePropagation(ctx); configureConsole(ctx); if (helper.isAllLogsToConsoleEnabled(appSettings.getProps()) || !appSettings.getProps().valueAsBoolean("sonar.wrapped", false)) { configureWithLogbackWritingToFile(ctx); } else { configureWithWrapperWritingToFile(ctx); } helper.apply( LogLevelConfig.newBuilder(helper.getRootLoggerName()) .rootLevelFor(ProcessId.APP) .immutableLevel("com.hazelcast", Level.toLevel("WARN")) .build(), appSettings.getProps()); return ctx; }
/** * Make the logback configuration for a sub process to correctly push all its logs to be read by a stream gobbler * on the sub process's System.out. * * @see #buildLogPattern(RootLoggerConfig) */ public void configureForSubprocessGobbler(Props props, String logPattern) { if (isAllLogsToConsoleEnabled(props)) { LoggerContext ctx = getRootContext(); ctx.getLogger(ROOT_LOGGER_NAME).addAppender(newConsoleAppender(ctx, "root_console", logPattern)); } }
/** * Make logback configuration for a process to push all its logs to a log file. * <p> * <ul> * <li>the file's name will use the prefix defined in {@link RootLoggerConfig#getProcessId()#getLogFilenamePrefix()}.</li> * <li>the file will follow the rotation policy defined in property {@link #ROLLING_POLICY_PROPERTY} and * the max number of files defined in property {@link #MAX_FILES_PROPERTY}</li> * <li>the logs will follow the specified log pattern</li> * </ul> * </p> * * @see #buildLogPattern(RootLoggerConfig) */ public FileAppender<ILoggingEvent> configureGlobalFileLog(Props props, RootLoggerConfig config, String logPattern) { LoggerContext ctx = getRootContext(); Logger rootLogger = ctx.getLogger(ROOT_LOGGER_NAME); FileAppender<ILoggingEvent> fileAppender = newFileAppender(ctx, props, config, logPattern); rootLogger.addAppender(fileAppender); return fileAppender; }
public void changeRoot(LogLevelConfig logLevelConfig, Level newLevel) { ensureSupportedLevel(newLevel); LoggerContext rootContext = getRootContext(); rootContext.getLogger(ROOT_LOGGER_NAME).setLevel(newLevel); logLevelConfig.getConfiguredByProperties().forEach((key, value) -> rootContext.getLogger(key).setLevel(newLevel)); }
@Test public void createRollingPolicy_fail_if_unknown_policy() { props.set("sonar.log.rollingPolicy", "unknown:foo"); try { LoggerContext ctx = underTest.getRootContext(); underTest.createRollingPolicy(ctx, props, "sonar"); fail(); } catch (MessageException e) { assertThat(e).hasMessage("Unsupported value for property sonar.log.rollingPolicy: unknown:foo"); } }
public LoggerContext configure(Props props) { LoggerContext ctx = helper.getRootContext(); ctx.reset(); configureRootLogger(props); helper.apply(logLevelConfig, props); configureDirectToConsoleLoggers(ctx, STARTUP_LOGGER_NAME); extendConfigure(); helper.enableJulChangePropagation(ctx); return ctx; }
public static <T> ListAppender attachMemoryAppenderToLoggerOf(Class<T> loggerClass) { ListAppender listAppender = new ListAppender(); new LogbackHelper().getRootContext().getLogger(loggerClass) .addAppender(listAppender); listAppender.start(); return listAppender; }
@Test public void apply_set_level_to_OFF_if_sonar_global_level_is_not_set() { LoggerContext context = underTest.apply(newLogLevelConfig().offUnlessTrace("fii").build(), new Props(new Properties())); assertThat(context.getLogger("fii").getLevel()).isEqualTo(Level.OFF); }
private static void configureLogbackAccess(Tomcat tomcat, Props props) { if (props.valueAsBoolean(PROPERTY_ENABLE, true)) { ProgrammaticLogbackValve valve = new ProgrammaticLogbackValve(); LogbackHelper helper = new LogbackHelper(); LogbackHelper.RollingPolicy policy = helper.createRollingPolicy(valve, props, "access"); FileAppender appender = policy.createAppender("ACCESS_LOG"); PatternLayoutEncoder fileEncoder = new PatternLayoutEncoder(); fileEncoder.setContext(valve); fileEncoder.setPattern(props.value(PROPERTY_PATTERN, DEFAULT_SQ_ACCESS_LOG_PATTERN)); fileEncoder.start(); appender.setEncoder(fileEncoder); appender.start(); valve.addAppender(appender); tomcat.getHost().getPipeline().addValve(valve); } }
/** * Setup one or more specified loggers to be non additive and to print to System.out which will be caught by the Main * Process and written to sonar.log. */ private void configureDirectToConsoleLoggers(LoggerContext context, String... loggerNames) { RootLoggerConfig config = newRootLoggerConfigBuilder() .setProcessId(ProcessId.APP) .setThreadIdFieldPattern("") .build(); String logPattern = helper.buildLogPattern(config); ConsoleAppender<ILoggingEvent> consoleAppender = helper.newConsoleAppender(context, "CONSOLE", logPattern); for (String loggerName : loggerNames) { Logger consoleLogger = context.getLogger(loggerName); consoleLogger.setAdditive(false); consoleLogger.addAppender(consoleAppender); } }
private ConsoleAppender<ILoggingEvent> createAppConsoleAppender(LoggerContext ctx, String appLogPattern) { return helper.newConsoleAppender(ctx, APP_CONSOLE_APPENDER, appLogPattern); }
@Test public void newConsoleAppender() { LoggerContext ctx = underTest.getRootContext(); ConsoleAppender<?> appender = underTest.newConsoleAppender(ctx, "MY_APPENDER", "%msg%n"); assertThat(appender.getName()).isEqualTo("MY_APPENDER"); assertThat(appender.getContext()).isSameAs(ctx); assertThat(appender.isStarted()).isTrue(); assertThat(((PatternLayoutEncoder) appender.getEncoder()).getPattern()).isEqualTo("%msg%n"); assertThat(appender.getCopyOfAttachedFiltersList()).isEmpty(); }
public ServerLogging(Configuration config, ServerProcessLogging serverProcessLogging, Database database) { this(new LogbackHelper(), config, serverProcessLogging, database); }
/** * Applies the specified {@link LogLevelConfig} reading the specified {@link Props}. * * @throws IllegalArgumentException if the any level specified in a property is not one of {@link #ALLOWED_ROOT_LOG_LEVELS} */ public LoggerContext apply(LogLevelConfig logLevelConfig, Props props) { if (!ROOT_LOGGER_NAME.equals(logLevelConfig.getRootLoggerName())) { throw new IllegalArgumentException("Value of LogLevelConfig#rootLoggerName must be \"" + ROOT_LOGGER_NAME + "\""); } LoggerContext rootContext = getRootContext(); logLevelConfig.getConfiguredByProperties().forEach((key, value) -> applyLevelByProperty(props, rootContext.getLogger(key), value)); logLevelConfig.getConfiguredByHardcodedLevel().forEach((key, value) -> applyHardcodedLevel(rootContext, key, value)); Level propertyValueAsLevel = getPropertyValueAsLevel(props, SONAR_LOG_LEVEL_PROPERTY); boolean traceGloballyEnabled = propertyValueAsLevel == Level.TRACE; logLevelConfig.getOffUnlessTrace().forEach(logger -> applyHardUnlessTrace(rootContext, logger, traceGloballyEnabled)); return rootContext; }
@Test public void enableJulChangePropagation() { LoggerContext ctx = underTest.getRootContext(); int countListeners = ctx.getCopyOfListenerList().size(); LoggerContextListener propagator = underTest.enableJulChangePropagation(ctx); assertThat(ctx.getCopyOfListenerList().size()).isEqualTo(countListeners + 1); ctx.removeListener(propagator); }
@Test public void apply_does_not_set_level_if_sonar_global_level_is_TRACE() { Properties properties = new Properties(); properties.setProperty("sonar.log.level", Level.TRACE.toString()); assertThat(underTest.getRootContext().getLogger("fii").getLevel()).isNull(); LoggerContext context = underTest.apply(newLogLevelConfig().offUnlessTrace("fii").build(), new Props(properties)); assertThat(context.getLogger("fii").getLevel()).isNull(); }
private void configureRootLogger(Props props) { RootLoggerConfig config = newRootLoggerConfigBuilder() .setProcessId(processId) .setThreadIdFieldPattern(threadIdFieldPattern) .build(); String logPattern = helper.buildLogPattern(config); helper.configureGlobalFileLog(props, config, logPattern); helper.configureForSubprocessGobbler(props, logPattern); }
/** * SQ has been started by the wrapper (ie. with sonar.sh) therefor, APP's System.out (and System.err) are written to * sonar.log by the wrapper. */ private void configureWithWrapperWritingToFile(LoggerContext ctx) { // configure all logs (ie. root logger) to be written to console with formatting // in practice, this will be only APP's own logs as logs from sub processes are written to LOGGER_GOBBLER and // LOGGER_GOBBLER is configured below to be detached from root // logs are written to the console because we want them to be in sonar.log and the wrapper will write any log // from APP's System.out and System.err to sonar.log Logger rootLogger = ctx.getLogger(ROOT_LOGGER_NAME); rootLogger.addAppender(createAppConsoleAppender(ctx, helper.buildLogPattern(APP_ROOT_LOGGER_CONFIG))); // in regular configuration, sub processes are not copying their logs to their System.out, so, the only logs to be // expected in LOGGER_GOBBLER are those before logback is setup in subprocesses or when JVM crashes // so, they must be printed to App's System.out as is (as they are already formatted) and the wrapper will write // them to sonar.log // logger is configured to be non additive as we don't want these logs written to sonar.log and duplicated in the // console with an incorrect formatting configureGobbler(ctx); }
private void configureRootWithLogbackWritingToFile(LoggerContext ctx) { Logger rootLogger = ctx.getLogger(ROOT_LOGGER_NAME); String appLogPattern = helper.buildLogPattern(APP_ROOT_LOGGER_CONFIG); FileAppender<ILoggingEvent> fileAppender = helper.newFileAppender(ctx, appSettings.getProps(), APP_ROOT_LOGGER_CONFIG, appLogPattern); rootLogger.addAppender(fileAppender); rootLogger.addAppender(createAppConsoleAppender(ctx, appLogPattern)); }