You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

WebServerProcessLoggingTest.java 22KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631
  1. /*
  2. * SonarQube
  3. * Copyright (C) 2009-2024 SonarSource SA
  4. * mailto:info AT sonarsource DOT com
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 3 of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public License
  17. * along with this program; if not, write to the Free Software Foundation,
  18. * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  19. */
  20. package org.sonar.server.app;
  21. import ch.qos.logback.classic.Level;
  22. import ch.qos.logback.classic.Logger;
  23. import ch.qos.logback.classic.LoggerContext;
  24. import ch.qos.logback.classic.spi.ILoggingEvent;
  25. import ch.qos.logback.core.Appender;
  26. import ch.qos.logback.core.AppenderBase;
  27. import ch.qos.logback.core.ConsoleAppender;
  28. import ch.qos.logback.core.FileAppender;
  29. import ch.qos.logback.core.OutputStreamAppender;
  30. import ch.qos.logback.core.encoder.Encoder;
  31. import ch.qos.logback.core.encoder.LayoutWrappingEncoder;
  32. import ch.qos.logback.core.joran.spi.JoranException;
  33. import com.google.common.collect.ImmutableList;
  34. import java.io.File;
  35. import java.io.IOException;
  36. import java.util.ArrayList;
  37. import java.util.List;
  38. import java.util.Properties;
  39. import java.util.stream.Stream;
  40. import org.junit.AfterClass;
  41. import org.junit.Before;
  42. import org.junit.Rule;
  43. import org.junit.Test;
  44. import org.junit.rules.TemporaryFolder;
  45. import org.sonar.process.Props;
  46. import org.sonar.process.logging.LogbackHelper;
  47. import org.sonar.process.logging.LogbackJsonLayout;
  48. import org.sonar.process.logging.PatternLayoutEncoder;
  49. import static org.assertj.core.api.Assertions.assertThat;
  50. import static org.assertj.core.api.Assertions.assertThatThrownBy;
  51. import static org.slf4j.Logger.ROOT_LOGGER_NAME;
  52. import static org.sonar.process.ProcessProperties.Property.PATH_LOGS;
  53. public class WebServerProcessLoggingTest {
  54. @Rule
  55. public TemporaryFolder temp = new TemporaryFolder();
  56. private File logDir;
  57. private final Props props = new Props(new Properties());
  58. private final WebServerProcessLogging underTest = new WebServerProcessLogging();
  59. @Before
  60. public void setUp() throws IOException {
  61. logDir = temp.newFolder();
  62. props.set(PATH_LOGS.getKey(), logDir.getAbsolutePath());
  63. }
  64. @AfterClass
  65. public static void resetLogback() throws JoranException {
  66. new LogbackHelper().resetFromXml("/logback-test.xml");
  67. }
  68. @Test
  69. public void do_not_log_to_console() {
  70. LoggerContext ctx = underTest.configure(props);
  71. Logger root = ctx.getLogger(Logger.ROOT_LOGGER_NAME);
  72. Appender appender = root.getAppender("CONSOLE");
  73. assertThat(appender).isNull();
  74. }
  75. @Test
  76. public void check_level_of_jul() throws IOException {
  77. Props props = new Props(new Properties());
  78. File dir = temp.newFolder();
  79. props.set(PATH_LOGS.getKey(), dir.getAbsolutePath());
  80. props.set("sonar.log.level.web", "TRACE");
  81. LoggerContext ctx = underTest.configure(props);
  82. MemoryAppender memoryAppender = new MemoryAppender();
  83. memoryAppender.start();
  84. ctx.getLogger(ROOT_LOGGER_NAME).addAppender(memoryAppender);
  85. java.util.logging.Logger logger = java.util.logging.Logger.getLogger("com.ms.sqlserver.jdbc.DTV");
  86. logger.finest("Test");
  87. memoryAppender.stop();
  88. assertThat(memoryAppender.getLogs()).hasSize(1);
  89. }
  90. @Test
  91. public void startup_logger_prints_to_only_to_system_out() {
  92. LoggerContext ctx = underTest.configure(props);
  93. Logger startup = ctx.getLogger("startup");
  94. assertThat(startup.isAdditive()).isFalse();
  95. Appender appender = startup.getAppender("CONSOLE");
  96. assertThat(appender).isInstanceOf(ConsoleAppender.class);
  97. ConsoleAppender<ILoggingEvent> consoleAppender = (ConsoleAppender<ILoggingEvent>) appender;
  98. assertThat(consoleAppender.getTarget()).isEqualTo("System.out");
  99. assertThat(consoleAppender.getEncoder()).isInstanceOf(PatternLayoutEncoder.class);
  100. PatternLayoutEncoder patternEncoder = (PatternLayoutEncoder) consoleAppender.getEncoder();
  101. assertThat(patternEncoder.getPattern()).isEqualTo("%d{yyyy.MM.dd HH:mm:ss} %-5level app[][%logger{20}] %msg%n");
  102. }
  103. @Test
  104. public void log_to_web_file() {
  105. LoggerContext ctx = underTest.configure(props);
  106. Logger root = ctx.getLogger(Logger.ROOT_LOGGER_NAME);
  107. Appender<ILoggingEvent> appender = root.getAppender("file_web");
  108. assertThat(appender).isInstanceOf(FileAppender.class);
  109. FileAppender fileAppender = (FileAppender) appender;
  110. assertThat(fileAppender.getFile()).isEqualTo(new File(logDir, "web.log").getAbsolutePath());
  111. assertThat(fileAppender.getEncoder()).isInstanceOf(PatternLayoutEncoder.class);
  112. PatternLayoutEncoder encoder = (PatternLayoutEncoder) fileAppender.getEncoder();
  113. assertThat(encoder.getPattern()).isEqualTo("%d{yyyy.MM.dd HH:mm:ss} %-5level web[%X{HTTP_REQUEST_ID}][%logger{20}] %msg%n");
  114. }
  115. @Test
  116. public void log_for_cluster_changes_layout_in_file_and_console() {
  117. props.set("sonar.cluster.enabled", "true");
  118. props.set("sonar.cluster.node.name", "my-node");
  119. LoggerContext ctx = underTest.configure(props);
  120. Logger root = ctx.getLogger(Logger.ROOT_LOGGER_NAME);
  121. FileAppender fileAppender = (FileAppender) root.getAppender("file_web");
  122. PatternLayoutEncoder encoder = (PatternLayoutEncoder) fileAppender.getEncoder();
  123. assertThat(encoder.getPattern()).isEqualTo("%d{yyyy.MM.dd HH:mm:ss} %-5level my-node web[%X{HTTP_REQUEST_ID}][%logger{20}] %msg%n");
  124. Logger startup = ctx.getLogger("startup");
  125. ConsoleAppender<ILoggingEvent> consoleAppender = (ConsoleAppender<ILoggingEvent>) startup.getAppender("CONSOLE");
  126. PatternLayoutEncoder patternEncoder = (PatternLayoutEncoder) consoleAppender.getEncoder();
  127. assertThat(patternEncoder.getPattern()).isEqualTo("%d{yyyy.MM.dd HH:mm:ss} %-5level my-node app[][%logger{20}] %msg%n");
  128. }
  129. @Test
  130. public void default_level_for_root_logger_is_INFO() {
  131. LoggerContext ctx = underTest.configure(props);
  132. verifyRootLogLevel(ctx, Level.INFO);
  133. }
  134. @Test
  135. public void root_logger_level_changes_with_global_property() {
  136. props.set("sonar.log.level", "TRACE");
  137. LoggerContext ctx = underTest.configure(props);
  138. verifyRootLogLevel(ctx, Level.TRACE);
  139. }
  140. @Test
  141. public void root_logger_level_changes_with_web_property() {
  142. props.set("sonar.log.level.web", "TRACE");
  143. LoggerContext ctx = underTest.configure(props);
  144. verifyRootLogLevel(ctx, Level.TRACE);
  145. }
  146. @Test
  147. public void root_logger_level_is_configured_from_web_property_over_global_property() {
  148. props.set("sonar.log.level", "TRACE");
  149. props.set("sonar.log.level.web", "DEBUG");
  150. LoggerContext ctx = underTest.configure(props);
  151. verifyRootLogLevel(ctx, Level.DEBUG);
  152. }
  153. @Test
  154. public void root_logger_level_changes_with_web_property_and_is_case_insensitive() {
  155. props.set("sonar.log.level.web", "debug");
  156. LoggerContext ctx = underTest.configure(props);
  157. verifyRootLogLevel(ctx, Level.DEBUG);
  158. }
  159. @Test
  160. public void sql_logger_level_changes_with_global_property_and_is_case_insensitive() {
  161. props.set("sonar.log.level", "InFO");
  162. LoggerContext ctx = underTest.configure(props);
  163. verifySqlLogLevel(ctx, Level.INFO);
  164. }
  165. @Test
  166. public void sql_logger_level_changes_with_web_property_and_is_case_insensitive() {
  167. props.set("sonar.log.level.web", "TrACe");
  168. LoggerContext ctx = underTest.configure(props);
  169. verifySqlLogLevel(ctx, Level.TRACE);
  170. }
  171. @Test
  172. public void sql_logger_level_changes_with_web_sql_property_and_is_case_insensitive() {
  173. props.set("sonar.log.level.web.sql", "debug");
  174. LoggerContext ctx = underTest.configure(props);
  175. verifySqlLogLevel(ctx, Level.DEBUG);
  176. }
  177. @Test
  178. public void sql_logger_level_is_configured_from_web_sql_property_over_web_property() {
  179. props.set("sonar.log.level.web.sql", "debug");
  180. props.set("sonar.log.level.web", "TRACE");
  181. LoggerContext ctx = underTest.configure(props);
  182. verifySqlLogLevel(ctx, Level.DEBUG);
  183. }
  184. @Test
  185. public void sql_logger_level_is_configured_from_web_sql_property_over_global_property() {
  186. props.set("sonar.log.level.web.sql", "debug");
  187. props.set("sonar.log.level", "TRACE");
  188. LoggerContext ctx = underTest.configure(props);
  189. verifySqlLogLevel(ctx, Level.DEBUG);
  190. }
  191. @Test
  192. public void sql_logger_level_is_configured_from_web_property_over_global_property() {
  193. props.set("sonar.log.level.web", "debug");
  194. props.set("sonar.log.level", "TRACE");
  195. LoggerContext ctx = underTest.configure(props);
  196. verifySqlLogLevel(ctx, Level.DEBUG);
  197. }
  198. @Test
  199. public void es_logger_level_changes_with_global_property_and_is_case_insensitive() {
  200. props.set("sonar.log.level", "InFO");
  201. LoggerContext ctx = underTest.configure(props);
  202. verifyEsLogLevel(ctx, Level.INFO);
  203. }
  204. @Test
  205. public void es_logger_level_changes_with_web_property_and_is_case_insensitive() {
  206. props.set("sonar.log.level.web", "TrACe");
  207. LoggerContext ctx = underTest.configure(props);
  208. verifyEsLogLevel(ctx, Level.TRACE);
  209. }
  210. @Test
  211. public void es_logger_level_changes_with_web_es_property_and_is_case_insensitive() {
  212. props.set("sonar.log.level.web.es", "debug");
  213. LoggerContext ctx = underTest.configure(props);
  214. verifyEsLogLevel(ctx, Level.DEBUG);
  215. }
  216. @Test
  217. public void es_logger_level_is_configured_from_web_es_property_over_web_property() {
  218. props.set("sonar.log.level.web.es", "debug");
  219. props.set("sonar.log.level.web", "TRACE");
  220. LoggerContext ctx = underTest.configure(props);
  221. verifyEsLogLevel(ctx, Level.DEBUG);
  222. }
  223. @Test
  224. public void es_logger_level_is_configured_from_web_es_property_over_global_property() {
  225. props.set("sonar.log.level.web.es", "debug");
  226. props.set("sonar.log.level", "TRACE");
  227. LoggerContext ctx = underTest.configure(props);
  228. verifyEsLogLevel(ctx, Level.DEBUG);
  229. }
  230. @Test
  231. public void es_logger_level_is_configured_from_web_property_over_global_property() {
  232. props.set("sonar.log.level.web", "debug");
  233. props.set("sonar.log.level", "TRACE");
  234. LoggerContext ctx = underTest.configure(props);
  235. verifyEsLogLevel(ctx, Level.DEBUG);
  236. }
  237. @Test
  238. public void jmx_logger_level_changes_with_global_property_and_is_case_insensitive() {
  239. props.set("sonar.log.level", "InFO");
  240. LoggerContext ctx = underTest.configure(props);
  241. verifyJmxLogLevel(ctx, Level.INFO);
  242. }
  243. @Test
  244. public void jmx_logger_level_changes_with_jmx_property_and_is_case_insensitive() {
  245. props.set("sonar.log.level.web", "TrACe");
  246. LoggerContext ctx = underTest.configure(props);
  247. verifyJmxLogLevel(ctx, Level.TRACE);
  248. }
  249. @Test
  250. public void jmx_logger_level_changes_with_web_jmx_property_and_is_case_insensitive() {
  251. props.set("sonar.log.level.web.jmx", "debug");
  252. LoggerContext ctx = underTest.configure(props);
  253. verifyJmxLogLevel(ctx, Level.DEBUG);
  254. }
  255. @Test
  256. public void jmx_logger_level_is_configured_from_web_jmx_property_over_web_property() {
  257. props.set("sonar.log.level.web.jmx", "debug");
  258. props.set("sonar.log.level.web", "TRACE");
  259. LoggerContext ctx = underTest.configure(props);
  260. verifyJmxLogLevel(ctx, Level.DEBUG);
  261. }
  262. @Test
  263. public void jmx_logger_level_is_configured_from_web_jmx_property_over_global_property() {
  264. props.set("sonar.log.level.web.jmx", "debug");
  265. props.set("sonar.log.level", "TRACE");
  266. LoggerContext ctx = underTest.configure(props);
  267. verifyJmxLogLevel(ctx, Level.DEBUG);
  268. }
  269. @Test
  270. public void jmx_logger_level_is_configured_from_web_property_over_global_property() {
  271. props.set("sonar.log.level.web", "debug");
  272. props.set("sonar.log.level", "TRACE");
  273. LoggerContext ctx = underTest.configure(props);
  274. verifyJmxLogLevel(ctx, Level.DEBUG);
  275. }
  276. @Test
  277. public void root_logger_level_defaults_to_INFO_if_web_property_has_invalid_value() {
  278. props.set("sonar.log.level.web", "DodoDouh!");
  279. LoggerContext ctx = underTest.configure(props);
  280. verifyRootLogLevel(ctx, Level.INFO);
  281. }
  282. @Test
  283. public void sql_logger_level_defaults_to_INFO_if_web_sql_property_has_invalid_value() {
  284. props.set("sonar.log.level.web.sql", "DodoDouh!");
  285. LoggerContext ctx = underTest.configure(props);
  286. verifySqlLogLevel(ctx, Level.INFO);
  287. }
  288. @Test
  289. public void es_logger_level_defaults_to_INFO_if_web_es_property_has_invalid_value() {
  290. props.set("sonar.log.level.web.es", "DodoDouh!");
  291. LoggerContext ctx = underTest.configure(props);
  292. verifyEsLogLevel(ctx, Level.INFO);
  293. }
  294. @Test
  295. public void jmx_loggers_level_defaults_to_INFO_if_wedb_jmx_property_has_invalid_value() {
  296. props.set("sonar.log.level.web.jmx", "DodoDouh!");
  297. LoggerContext ctx = underTest.configure(props);
  298. verifyJmxLogLevel(ctx, Level.INFO);
  299. }
  300. @Test
  301. public void fail_with_IAE_if_global_property_unsupported_level() {
  302. props.set("sonar.log.level", "ERROR");
  303. assertThatThrownBy(() -> underTest.configure(props))
  304. .isInstanceOf(IllegalArgumentException.class)
  305. .hasMessage("log level ERROR in property sonar.log.level is not a supported value (allowed levels are [TRACE, DEBUG, INFO])");
  306. }
  307. @Test
  308. public void fail_with_IAE_if_web_property_unsupported_level() {
  309. props.set("sonar.log.level.web", "ERROR");
  310. assertThatThrownBy(() -> underTest.configure(props))
  311. .isInstanceOf(IllegalArgumentException.class)
  312. .hasMessage("log level ERROR in property sonar.log.level.web is not a supported value (allowed levels are [TRACE, DEBUG, INFO])");
  313. }
  314. @Test
  315. public void fail_with_IAE_if_web_sql_property_unsupported_level() {
  316. props.set("sonar.log.level.web.sql", "ERROR");
  317. assertThatThrownBy(() -> underTest.configure(props))
  318. .isInstanceOf(IllegalArgumentException.class)
  319. .hasMessage("log level ERROR in property sonar.log.level.web.sql is not a supported value (allowed levels are [TRACE, DEBUG, INFO])");
  320. }
  321. @Test
  322. public void fail_with_IAE_if_web_es_property_unsupported_level() {
  323. props.set("sonar.log.level.web.es", "ERROR");
  324. assertThatThrownBy(() -> underTest.configure(props))
  325. .isInstanceOf(IllegalArgumentException.class)
  326. .hasMessage("log level ERROR in property sonar.log.level.web.es is not a supported value (allowed levels are [TRACE, DEBUG, INFO])");
  327. }
  328. @Test
  329. public void fail_with_IAE_if_web_jmx_property_unsupported_level() {
  330. props.set("sonar.log.level.web.jmx", "ERROR");
  331. assertThatThrownBy(() -> underTest.configure(props))
  332. .isInstanceOf(IllegalArgumentException.class)
  333. .hasMessage("log level ERROR in property sonar.log.level.web.jmx is not a supported value (allowed levels are [TRACE, DEBUG, INFO])");
  334. }
  335. @Test
  336. public void configure_defines_hardcoded_levels() {
  337. LoggerContext context = underTest.configure(props);
  338. verifyImmutableLogLevels(context);
  339. }
  340. @Test
  341. public void configure_defines_hardcoded_levels_unchanged_by_global_property() {
  342. props.set("sonar.log.level", "TRACE");
  343. LoggerContext context = underTest.configure(props);
  344. verifyImmutableLogLevels(context);
  345. }
  346. @Test
  347. public void configure_defines_hardcoded_levels_unchanged_by_ce_property() {
  348. props.set("sonar.log.level.ce", "TRACE");
  349. LoggerContext context = underTest.configure(props);
  350. verifyImmutableLogLevels(context);
  351. }
  352. @Test
  353. public void configure_turns_off_some_Tomcat_loggers_if_global_log_level_is_not_set() {
  354. LoggerContext context = underTest.configure(props);
  355. verifyTomcatLoggersLogLevelsOff(context);
  356. }
  357. @Test
  358. public void configure_turns_off_some_Tomcat_loggers_if_global_log_level_is_INFO() {
  359. props.set("sonar.log.level", "INFO");
  360. LoggerContext context = underTest.configure(props);
  361. verifyTomcatLoggersLogLevelsOff(context);
  362. }
  363. @Test
  364. public void configure_turns_off_some_Tomcat_loggers_if_global_log_level_is_DEBUG() {
  365. props.set("sonar.log.level", "DEBUG");
  366. LoggerContext context = underTest.configure(props);
  367. verifyTomcatLoggersLogLevelsOff(context);
  368. }
  369. @Test
  370. public void configure_turns_off_some_Tomcat_loggers_if_global_log_level_is_TRACE() {
  371. props.set("sonar.log.level", "TRACE");
  372. LoggerContext context = underTest.configure(props);
  373. assertThat(context.getLogger("org.apache.catalina.core.ContainerBase").getLevel()).isNull();
  374. assertThat(context.getLogger("org.apache.catalina.core.StandardContext").getLevel()).isNull();
  375. assertThat(context.getLogger("org.apache.catalina.core.StandardService").getLevel()).isNull();
  376. }
  377. @Test
  378. public void configure_turns_off_some_MsSQL_driver_logger() {
  379. LoggerContext context = underTest.configure(props);
  380. Stream.of("com.microsoft.sqlserver.jdbc.internals",
  381. "com.microsoft.sqlserver.jdbc.ResultSet",
  382. "com.microsoft.sqlserver.jdbc.Statement",
  383. "com.microsoft.sqlserver.jdbc.Connection")
  384. .forEach(loggerName -> assertThat(context.getLogger(loggerName).getLevel()).isEqualTo(Level.OFF));
  385. }
  386. @Test
  387. public void use_json_output() {
  388. props.set("sonar.log.jsonOutput", "true");
  389. LoggerContext context = underTest.configure(props);
  390. Logger rootLogger = context.getLogger(ROOT_LOGGER_NAME);
  391. OutputStreamAppender appender = (OutputStreamAppender) rootLogger.getAppender("file_web");
  392. Encoder<ILoggingEvent> encoder = appender.getEncoder();
  393. assertThat(encoder).isInstanceOf(LayoutWrappingEncoder.class);
  394. assertThat(((LayoutWrappingEncoder) encoder).getLayout()).isInstanceOf(LogbackJsonLayout.class);
  395. }
  396. @Test
  397. public void configure_whenJsonPropFalse_shouldConfigureDeprecatedLoggerWithPatternLayout() {
  398. props.set("sonar.log.jsonOutput", "false");
  399. LoggerContext context = underTest.configure(props);
  400. Logger logger = context.getLogger("SONAR_DEPRECATION");
  401. assertThat(logger.isAdditive()).isFalse();
  402. Appender<ILoggingEvent> appender = logger.getAppender("file_deprecation");
  403. assertThat(appender).isNotNull()
  404. .isInstanceOf(FileAppender.class);
  405. FileAppender<ILoggingEvent> fileAppender = (FileAppender<ILoggingEvent>) appender;
  406. Encoder<ILoggingEvent> encoder = fileAppender.getEncoder();
  407. assertThat(encoder).isInstanceOf(PatternLayoutEncoder.class);
  408. PatternLayoutEncoder patternLayoutEncoder = (PatternLayoutEncoder) encoder;
  409. assertThat(patternLayoutEncoder.getPattern()).isEqualTo("%d{yyyy.MM.dd HH:mm:ss} %-5level web[%X{HTTP_REQUEST_ID}] %X{LOGIN} %X{ENTRYPOINT} %msg%n");
  410. }
  411. @Test
  412. public void configure_whenJsonPropTrue_shouldConfigureDeprecatedLoggerWithJsonLayout() {
  413. props.set("sonar.log.jsonOutput", "true");
  414. LoggerContext context = underTest.configure(props);
  415. Logger logger = context.getLogger("SONAR_DEPRECATION");
  416. assertThat(logger.isAdditive()).isFalse();
  417. Appender<ILoggingEvent> appender = logger.getAppender("file_deprecation");
  418. assertThat(appender).isNotNull()
  419. .isInstanceOf(FileAppender.class);
  420. FileAppender<ILoggingEvent> fileAppender = (FileAppender<ILoggingEvent>) appender;
  421. assertThat(fileAppender.getEncoder()).isInstanceOf(LayoutWrappingEncoder.class);
  422. }
  423. @Test
  424. public void configure_shouldConfigureDeprecatedLoggerWithConsoleAppender() {
  425. LoggerContext ctx = underTest.configure(props);
  426. Logger root = ctx.getLogger("SONAR_DEPRECATION");
  427. Appender<ILoggingEvent> appender = root.getAppender("CONSOLE");
  428. assertThat(appender).isNotNull();
  429. }
  430. private void verifyRootLogLevel(LoggerContext ctx, Level expected) {
  431. Logger rootLogger = ctx.getLogger(ROOT_LOGGER_NAME);
  432. assertThat(rootLogger.getLevel()).isEqualTo(expected);
  433. }
  434. private void verifySqlLogLevel(LoggerContext ctx, Level expected) {
  435. assertThat(ctx.getLogger("sql").getLevel()).isEqualTo(expected);
  436. }
  437. private void verifyEsLogLevel(LoggerContext ctx, Level expected) {
  438. assertThat(ctx.getLogger("es").getLevel()).isEqualTo(expected);
  439. }
  440. private void verifyJmxLogLevel(LoggerContext ctx, Level expected) {
  441. assertThat(ctx.getLogger("javax.management.remote.timeout").getLevel()).isEqualTo(expected);
  442. assertThat(ctx.getLogger("javax.management.remote.misc").getLevel()).isEqualTo(expected);
  443. assertThat(ctx.getLogger("javax.management.remote.rmi").getLevel()).isEqualTo(expected);
  444. assertThat(ctx.getLogger("javax.management.mbeanserver").getLevel()).isEqualTo(expected);
  445. assertThat(ctx.getLogger("sun.rmi.loader").getLevel()).isEqualTo(expected);
  446. assertThat(ctx.getLogger("sun.rmi.transport.tcp").getLevel()).isEqualTo(expected);
  447. assertThat(ctx.getLogger("sun.rmi.transport.misc").getLevel()).isEqualTo(expected);
  448. assertThat(ctx.getLogger("sun.rmi.server.call").getLevel()).isEqualTo(expected);
  449. assertThat(ctx.getLogger("sun.rmi.dgc").getLevel()).isEqualTo(expected);
  450. }
  451. private void verifyImmutableLogLevels(LoggerContext ctx) {
  452. assertThat(ctx.getLogger("org.apache.ibatis").getLevel()).isEqualTo(Level.WARN);
  453. assertThat(ctx.getLogger("java.sql").getLevel()).isEqualTo(Level.WARN);
  454. assertThat(ctx.getLogger("java.sql.ResultSet").getLevel()).isEqualTo(Level.WARN);
  455. assertThat(ctx.getLogger("org.elasticsearch").getLevel()).isEqualTo(Level.INFO);
  456. assertThat(ctx.getLogger("org.elasticsearch.node").getLevel()).isEqualTo(Level.INFO);
  457. assertThat(ctx.getLogger("org.elasticsearch.http").getLevel()).isEqualTo(Level.INFO);
  458. assertThat(ctx.getLogger("ch.qos.logback").getLevel()).isEqualTo(Level.WARN);
  459. assertThat(ctx.getLogger("org.apache.catalina").getLevel()).isEqualTo(Level.INFO);
  460. assertThat(ctx.getLogger("org.apache.coyote").getLevel()).isEqualTo(Level.INFO);
  461. assertThat(ctx.getLogger("org.apache.jasper").getLevel()).isEqualTo(Level.INFO);
  462. assertThat(ctx.getLogger("org.apache.tomcat").getLevel()).isEqualTo(Level.INFO);
  463. }
  464. private void verifyTomcatLoggersLogLevelsOff(LoggerContext context) {
  465. assertThat(context.getLogger("org.apache.catalina.core.ContainerBase").getLevel()).isEqualTo(Level.OFF);
  466. assertThat(context.getLogger("org.apache.catalina.core.StandardContext").getLevel()).isEqualTo(Level.OFF);
  467. assertThat(context.getLogger("org.apache.catalina.core.StandardService").getLevel()).isEqualTo(Level.OFF);
  468. }
  469. public static class MemoryAppender extends AppenderBase<ILoggingEvent> {
  470. private static final List<ILoggingEvent> LOGS = new ArrayList<>();
  471. @Override
  472. protected void append(ILoggingEvent eventObject) {
  473. LOGS.add(eventObject);
  474. }
  475. public List<ILoggingEvent> getLogs() {
  476. return ImmutableList.copyOf(LOGS);
  477. }
  478. public void clear() {
  479. LOGS.clear();
  480. }
  481. }
  482. }