├── .github └── dependabot.yml ├── .gitignore ├── LICENSE ├── README.adoc ├── benchmark ├── pom.xml └── src │ └── main │ ├── java │ └── net │ │ └── openhft │ │ └── Lo4J2PerfTest.java │ └── resources │ └── log4j2.xml ├── docs └── images │ └── Logger_line.png ├── logger-core ├── pom.xml └── src │ ├── main │ └── java │ │ └── net │ │ └── openhft │ │ └── chronicle │ │ └── logger │ │ ├── ChronicleLogConfig.java │ │ ├── ChronicleLogLevel.java │ │ ├── ChronicleLogManager.java │ │ ├── ChronicleLogWriter.java │ │ ├── DefaultChronicleLogWriter.java │ │ ├── LogAppenderConfig.java │ │ └── internal │ │ └── package-info.java │ └── test │ └── java │ └── net │ └── openhft │ └── chronicle │ └── logger │ └── DefaultChronicleLogWriterTest.java ├── logger-jcl ├── pom.xml └── src │ ├── main │ ├── java │ │ └── net │ │ │ └── openhft │ │ │ └── chronicle │ │ │ └── logger │ │ │ └── jcl │ │ │ ├── ChronicleLogger.java │ │ │ ├── ChronicleLoggerFactory.java │ │ │ └── internal │ │ │ └── package-info.java │ └── resources │ │ └── META-INF │ │ └── services │ │ └── org.apache.commons.logging.LogFactory │ └── test │ ├── java │ └── net │ │ └── openhft │ │ └── chronicle │ │ └── logger │ │ └── jcl │ │ ├── JclChronicleLoggerTest.java │ │ └── JclTestBase.java │ └── resources │ └── chronicle.logger.properties ├── logger-jul ├── pom.xml └── src │ ├── main │ └── java │ │ └── net │ │ └── openhft │ │ └── chronicle │ │ └── logger │ │ └── jul │ │ ├── AbstractChronicleHandler.java │ │ ├── ChronicleHandler.java │ │ ├── ChronicleHandlerConfig.java │ │ ├── ChronicleHelper.java │ │ ├── ChronicleLogger.java │ │ ├── ChronicleLoggerManager.java │ │ └── internal │ │ └── package-info.java │ └── test │ ├── java │ └── net │ │ └── openhft │ │ └── chronicle │ │ └── logger │ │ └── jul │ │ ├── JulHandlerChronicleTest.java │ │ ├── JulHandlerTestBase.java │ │ ├── JulLoggerChronicleTest.java │ │ ├── JulLoggerTestBase.java │ │ └── JulTestBase.java │ └── resources │ ├── JulLoggerChronicleTest.properties │ ├── binary-cfg.properties │ └── binary-chronicle.properties ├── logger-log4j-1 ├── pom.xml └── src │ ├── main │ └── java │ │ └── net │ │ └── openhft │ │ └── chronicle │ │ └── logger │ │ └── log4j1 │ │ ├── AbstractChronicleAppender.java │ │ ├── ChronicleAppender.java │ │ └── internal │ │ └── package-info.java │ └── test │ ├── java │ └── net │ │ └── openhft │ │ └── chronicle │ │ └── logger │ │ └── log4j1 │ │ ├── Log4j1ChronicleLogTest.java │ │ └── Log4j1TestBase.java │ └── resources │ └── log4j.xml ├── logger-log4j-2 ├── pom.xml └── src │ ├── main │ └── java │ │ └── net │ │ └── openhft │ │ └── chronicle │ │ └── logger │ │ └── log4j2 │ │ ├── AbstractChronicleAppender.java │ │ ├── ChronicleAppender.java │ │ └── internal │ │ └── package-info.java │ └── test │ ├── java │ └── net │ │ └── openhft │ │ └── chronicle │ │ └── logger │ │ └── log4j2 │ │ ├── Log4j2BinaryTest.java │ │ ├── Log4j2TestBase.java │ │ └── Log4j2VulnerabilityTest.java │ └── resources │ └── log4j2.xml ├── logger-logback ├── pom.xml └── src │ ├── main │ └── java │ │ └── net │ │ └── openhft │ │ └── chronicle │ │ └── logger │ │ └── logback │ │ ├── AbstractChronicleAppender.java │ │ ├── ChronicleAppender.java │ │ └── internal │ │ └── package-info.java │ └── test │ ├── java │ └── net │ │ └── openhft │ │ └── chronicle │ │ └── logger │ │ └── logback │ │ ├── LogbackChronicleBinaryAppenderTest.java │ │ ├── LogbackChronicleProgrammaticConfigTest.java │ │ ├── LogbackIndexedChronicleConfigTest.java │ │ └── LogbackTestBase.java │ └── resources │ ├── logback-chronicle-binary-appender.xml │ └── logback-chronicle-config.xml ├── logger-slf4j-2 ├── pom.xml └── src │ ├── main │ ├── java │ │ ├── net │ │ │ └── openhft │ │ │ │ └── chronicle │ │ │ │ └── logger │ │ │ │ └── slf4j2 │ │ │ │ ├── ChronicleLogger.java │ │ │ │ ├── ChronicleLoggerFactory.java │ │ │ │ └── internal │ │ │ │ └── package-info.java │ │ └── org │ │ │ └── slf4j │ │ │ └── impl │ │ │ ├── ChronicleServiceProvider.java │ │ │ ├── OutputChoice.java │ │ │ ├── SimpleLogger.java │ │ │ └── SimpleLoggerConfiguration.java │ └── resources │ │ └── META-INF │ │ └── services │ │ └── org.slf4j.spi.SLF4JServiceProvider │ └── test │ ├── java │ └── net │ │ └── openhft │ │ └── chronicle │ │ └── logger │ │ └── slf4j2 │ │ ├── ChronicleLoggingConfigTest.java │ │ ├── Slf4jChronicleConfigurationTest.java │ │ ├── Slf4jChronicleLoggerPerfTest.java │ │ ├── Slf4jChronicleLoggerTest.java │ │ └── Slf4jTestBase.java │ └── resources │ ├── chronicle.logger.perf.properties │ └── chronicle.logger.properties ├── logger-slf4j ├── pom.xml └── src │ ├── main │ └── java │ │ ├── net │ │ └── openhft │ │ │ └── chronicle │ │ │ └── logger │ │ │ └── slf4j │ │ │ ├── ChronicleLogger.java │ │ │ ├── ChronicleLoggerFactory.java │ │ │ └── internal │ │ │ └── package-info.java │ │ └── org │ │ └── slf4j │ │ └── impl │ │ ├── OutputChoice.java │ │ ├── SimpleLogger.java │ │ ├── SimpleLoggerConfiguration.java │ │ ├── StaticLoggerBinder.java │ │ └── StaticMarkerBinder.java │ └── test │ ├── java │ └── net │ │ └── openhft │ │ └── chronicle │ │ └── logger │ │ └── slf4j │ │ ├── ChronicleLoggingConfigTest.java │ │ ├── Slf4jChronicleConfigurationTest.java │ │ ├── Slf4jChronicleLoggerPerfTest.java │ │ ├── Slf4jChronicleLoggerTest.java │ │ └── Slf4jTestBase.java │ └── resources │ ├── chronicle.logger.perf.properties │ └── chronicle.logger.properties ├── logger-tools ├── pom.xml └── src │ ├── main │ └── java │ │ └── net │ │ └── openhft │ │ └── chronicle │ │ └── logger │ │ └── tools │ │ ├── ChroniCat.java │ │ ├── ChroniTail.java │ │ ├── ChronicleLogProcessor.java │ │ ├── ChronicleLogReader.java │ │ └── internal │ │ └── package-info.java │ └── test │ ├── java │ └── net │ │ └── openhft │ │ └── chronicle │ │ └── logger │ │ └── tools │ │ └── ChronicleLogReaderTest.java │ └── resources │ └── logback-chronicle-binary-appender.xml └── pom.xml /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "maven" 4 | directory: "/" 5 | schedule: 6 | interval: "daily" 7 | target-branch: "develop" 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ### How to update 2 | # This is copied from OpenHFT/.gitignore 3 | # update the original and run OpenHFT/update_gitignore.sh 4 | 5 | ### Compiled class file 6 | *.class 7 | 8 | ### Package Files 9 | *.jar 10 | *.war 11 | *.ear 12 | 13 | ### Log file 14 | *.log 15 | 16 | ### IntelliJ 17 | *.iml 18 | *.ipr 19 | *.iws 20 | .idea 21 | compat_reports 22 | .attach_pid* 23 | 24 | ### Virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 25 | hs_err_pid* 26 | 27 | ### Maven template 28 | target/ 29 | pom.xml.tag 30 | pom.xml.releaseBackup 31 | pom.xml.versionsBackup 32 | pom.xml.next 33 | release.properties 34 | 35 | ### Eclipse template 36 | *.pydevproject 37 | .metadata 38 | .gradle 39 | bin/ 40 | tmp/ 41 | *.tmp 42 | *.bak 43 | *.swp 44 | *~.nib 45 | local.properties 46 | .classpath 47 | .project 48 | .settings/ 49 | .loadpath 50 | 51 | ### Queue files 52 | *.cq4t 53 | *.cq4 54 | -------------------------------------------------------------------------------- /benchmark/src/main/java/net/openhft/Lo4J2PerfTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | 26 | package net.openhft; 27 | 28 | import net.openhft.chronicle.core.io.IOTools; 29 | import org.openjdk.jmh.annotations.*; 30 | import org.openjdk.jmh.runner.Runner; 31 | import org.openjdk.jmh.runner.RunnerException; 32 | import org.openjdk.jmh.runner.options.Options; 33 | import org.openjdk.jmh.runner.options.OptionsBuilder; 34 | import org.slf4j.Logger; 35 | import org.slf4j.LoggerFactory; 36 | 37 | import java.util.concurrent.TimeUnit; 38 | 39 | @State(Scope.Thread) 40 | public class Lo4J2PerfTest { 41 | private final Logger chronicleLogger = LoggerFactory.getLogger("perf-chro"); 42 | private final Logger fileLogger = LoggerFactory.getLogger("perf-file"); 43 | 44 | public static void main(String[] args) throws RunnerException { 45 | 46 | Options opt = new OptionsBuilder() 47 | .include(Lo4J2PerfTest.class.getSimpleName()) 48 | .warmupIterations(5) 49 | .measurementIterations(5) 50 | .forks(1) 51 | .build(); 52 | 53 | new Runner(opt).run(); 54 | 55 | } 56 | 57 | private static String rootPath() { 58 | // NB: 59 | // Be careful if using /tmp - quite often it's mounted as TMPFS, e.g. as RAM disk. 60 | // This will nullify the benefits of Chronicle Logger 61 | String path = System.getenv("HOME"); 62 | String sep = System.getProperty("file.separator"); 63 | 64 | if (!path.endsWith(sep)) { 65 | path += sep; 66 | } 67 | 68 | return path + "chronicle-log4j2-bench"; 69 | } 70 | 71 | @Benchmark 72 | @BenchmarkMode(Mode.AverageTime) 73 | @OutputTimeUnit(TimeUnit.NANOSECONDS) 74 | public void testChronicle() { 75 | chronicleLogger.debug("Test {} {} " + 1, 2, 3); 76 | } 77 | 78 | @Benchmark 79 | @BenchmarkMode(Mode.AverageTime) 80 | @OutputTimeUnit(TimeUnit.NANOSECONDS) 81 | public void testChronicleException() { 82 | chronicleLogger.debug("Throwable test 2", new UnsupportedOperationException("Exception message")); 83 | } 84 | 85 | @Benchmark 86 | @BenchmarkMode(Mode.AverageTime) 87 | @OutputTimeUnit(TimeUnit.NANOSECONDS) 88 | public void testFile() { 89 | fileLogger.debug("Test {} {} " + 1, 2, 3); 90 | } 91 | 92 | @Benchmark 93 | @BenchmarkMode(Mode.AverageTime) 94 | @OutputTimeUnit(TimeUnit.NANOSECONDS) 95 | public void testFileException() { 96 | fileLogger.debug("Throwable test 2", new UnsupportedOperationException("Exception message")); 97 | } 98 | 99 | @TearDown 100 | public void tearDown() { 101 | IOTools.deleteDirWithFiles(rootPath()); 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /benchmark/src/main/resources/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | ${env:HOME}/chronicle-log4j2-bench/perf-chronicle 34 | 35 | 36 | 37 | %d [%t] %p %c - %m %ex%n 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /docs/images/Logger_line.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenHFT/Chronicle-Logger/a81cdf7e656e28a65911c78b613fd8445ea093a9/docs/images/Logger_line.png -------------------------------------------------------------------------------- /logger-core/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 21 | 22 | 23 | 4.0.0 24 | 25 | 26 | net.openhft 27 | chronicle-logger 28 | 4.27ea2-SNAPSHOT 29 | ../pom.xml 30 | 31 | 32 | bundle 33 | OpenHFT/Chronicle-Logger/logger 34 | chronicle-logger-core 35 | 36 | 37 | 38 | net.openhft 39 | chronicle-wire 40 | 41 | 42 | 43 | org.slf4j 44 | slf4j-simple 45 | test 46 | 47 | 48 | 49 | 50 | 51 | 52 | org.apache.maven.plugins 53 | maven-surefire-plugin 54 | 55 | 56 | ${project.build.directory} 57 | 58 | 59 | 60 | **/*PerfTest.java 61 | 62 | 63 | 64 | 72 | 73 | org.apache.servicemix.tooling 74 | depends-maven-plugin 75 | 76 | 77 | generate-depends-file 78 | 79 | generate-depends-file 80 | 81 | 82 | 83 | 84 | 85 | org.apache.felix 86 | maven-bundle-plugin 87 | true 88 | 89 | 90 | ${project.groupId}.${project.artifactId} 91 | 92 | ${project.artifactId} 93 | net.openhft.chronicle.logger.* 94 | 95 | 96 | 97 | 101 | 102 | 103 | manifest 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /logger-core/src/main/java/net/openhft/chronicle/logger/ChronicleLogLevel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger; 19 | 20 | import org.jetbrains.annotations.NotNull; 21 | 22 | public enum ChronicleLogLevel { 23 | ERROR(50, "ERROR"), 24 | WARN(40, "WARN"), 25 | INFO(30, "INFO"), 26 | DEBUG(20, "DEBUG"), 27 | TRACE(10, "TRACE"); 28 | 29 | /** 30 | * Array is not cached in Java enum internals, make the single copy to prevent garbage creation 31 | */ 32 | private static final ChronicleLogLevel[] VALUES = values(); 33 | 34 | private static final int CASE_DIFF = 'A' - 'a'; 35 | 36 | private final int levelInt; 37 | private final String levelStr; 38 | 39 | ChronicleLogLevel(int levelInt, String levelStr) { 40 | this.levelInt = levelInt; 41 | this.levelStr = levelStr; 42 | } 43 | 44 | public static ChronicleLogLevel fromStringLevel(final CharSequence levelStr) { 45 | if (levelStr != null) { 46 | for (ChronicleLogLevel cll : VALUES) { 47 | if (fastEqualsIgnoreCase(cll.levelStr, levelStr)) { 48 | return cll; 49 | } 50 | } 51 | } 52 | 53 | throw new IllegalArgumentException(levelStr + " not a valid level value"); 54 | } 55 | 56 | /** 57 | * Package-private for testing. 58 | * 59 | * @param upperCase string of A-Z characters 60 | * @param other a {@code CharSequence} to compare 61 | * @return {@code true} if {@code upperCase} and {@code other} equals ignore case 62 | */ 63 | private static boolean fastEqualsIgnoreCase(@NotNull String upperCase, @NotNull CharSequence other) { 64 | int l; 65 | if ((l = upperCase.length()) != other.length()) { 66 | return false; 67 | } 68 | 69 | for (int i = 0; i < l; i++) { 70 | int uC, oC; 71 | if ((uC = upperCase.charAt(i)) != (oC = other.charAt(i)) && (uC != oC + CASE_DIFF)) { 72 | return false; 73 | } 74 | } 75 | 76 | return true; 77 | } 78 | 79 | public boolean isHigherOrEqualTo(final ChronicleLogLevel presumablyLowerLevel) { 80 | return levelInt >= presumablyLowerLevel.levelInt; 81 | } 82 | 83 | @Override 84 | public String toString() { 85 | return levelStr; 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /logger-core/src/main/java/net/openhft/chronicle/logger/ChronicleLogManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger; 19 | 20 | import net.openhft.chronicle.queue.ChronicleQueue; 21 | 22 | import java.io.IOException; 23 | import java.util.Map; 24 | import java.util.concurrent.ConcurrentHashMap; 25 | 26 | public class ChronicleLogManager { 27 | private ChronicleLogConfig cfg; 28 | private Map writers; 29 | 30 | private ChronicleLogManager() { 31 | this.cfg = ChronicleLogConfig.load(); 32 | this.writers = new ConcurrentHashMap<>(); 33 | } 34 | 35 | public static ChronicleLogManager getInstance() { 36 | return Holder.INSTANCE; 37 | } 38 | 39 | public ChronicleLogConfig cfg() { 40 | return this.cfg; 41 | } 42 | 43 | public void clear() { 44 | for (final ChronicleLogWriter writer : writers.values()) { 45 | try { 46 | writer.close(); 47 | } catch (IOException e) { 48 | } 49 | } 50 | 51 | writers.clear(); 52 | } 53 | 54 | public void reload() { 55 | clear(); 56 | 57 | this.cfg = ChronicleLogConfig.load(); 58 | this.writers = new ConcurrentHashMap<>(); 59 | } 60 | 61 | public ChronicleLogWriter getWriter(String name) { 62 | if (this.cfg == null) { 63 | throw new IllegalArgumentException("ChronicleLogManager is not configured"); 64 | } 65 | 66 | final String path = cfg.getString(name, ChronicleLogConfig.KEY_PATH); 67 | if (path != null) { 68 | // Creating a Queue takes some time. Other threads might be blocked for longer periods. 69 | return writers.computeIfAbsent(path, p-> new DefaultChronicleLogWriter(newChronicle(p, name))); 70 | } else { 71 | throw new IllegalArgumentException( 72 | "chronicle.logger.root.path is not defined, chronicle.logger." + name + ".path is not defined" 73 | ); 74 | } 75 | } 76 | 77 | // ************************************************************************* 78 | // 79 | // ************************************************************************* 80 | 81 | private ChronicleQueue newChronicle(String path, String name) { 82 | final String wireType = cfg.getString(name, ChronicleLogConfig.KEY_WIRETYPE); 83 | ChronicleQueue cq = this.cfg.getAppenderConfig().build(path, wireType); 84 | if (!cfg.getBoolean(name, ChronicleLogConfig.KEY_APPEND, true)) { 85 | // TODO re-enable when it's implemented. ATM it throws UnsupportedOperationException... 86 | //cq.clear(); 87 | } 88 | return cq; 89 | } 90 | 91 | // ************************************************************************* 92 | // 93 | // ************************************************************************* 94 | 95 | private static class Holder { 96 | private static final ChronicleLogManager INSTANCE = new ChronicleLogManager(); 97 | 98 | private Holder() { 99 | 100 | } 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /logger-core/src/main/java/net/openhft/chronicle/logger/ChronicleLogWriter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger; 19 | 20 | import java.io.Closeable; 21 | 22 | public interface ChronicleLogWriter extends Closeable { 23 | 24 | void write( 25 | ChronicleLogLevel level, 26 | long timestamp, 27 | String threadName, 28 | String loggerName, 29 | String message); 30 | 31 | void write( 32 | ChronicleLogLevel level, 33 | long timestamp, 34 | String threadName, 35 | String loggerName, 36 | String message, 37 | Throwable throwable, 38 | Object... args); 39 | 40 | } 41 | -------------------------------------------------------------------------------- /logger-core/src/main/java/net/openhft/chronicle/logger/DefaultChronicleLogWriter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger; 19 | 20 | import net.openhft.chronicle.queue.ChronicleQueue; 21 | import net.openhft.chronicle.queue.ExcerptAppender; 22 | import net.openhft.chronicle.wire.DocumentContext; 23 | import net.openhft.chronicle.wire.Wire; 24 | import net.openhft.chronicle.wire.WireType; 25 | import org.jetbrains.annotations.NotNull; 26 | 27 | import java.text.SimpleDateFormat; 28 | 29 | public class DefaultChronicleLogWriter implements ChronicleLogWriter { 30 | 31 | private static final ThreadLocal REENTRANCY_FLAG = ThreadLocal.withInitial(() -> false); 32 | private static final ThreadLocal tsFormatter = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS")); 33 | 34 | private final ChronicleQueue cq; 35 | 36 | public DefaultChronicleLogWriter(@NotNull ChronicleQueue cq) { 37 | this.cq = cq; 38 | } 39 | 40 | @Override 41 | public void close() { 42 | cq.close(); 43 | } 44 | 45 | @Override 46 | public void write( 47 | final ChronicleLogLevel level, 48 | final long timestamp, 49 | final String threadName, 50 | final String loggerName, 51 | final String message) { 52 | write(level, timestamp, threadName, loggerName, message, null); 53 | } 54 | 55 | @Override 56 | public void write( 57 | final ChronicleLogLevel level, 58 | final long timestamp, 59 | final String threadName, 60 | final String loggerName, 61 | final String message, 62 | final Throwable throwable, 63 | final Object... args) { 64 | if (REENTRANCY_FLAG.get()) { 65 | if (throwable == null) { 66 | System.out.printf("%s|%s|%s|%s|%s%n", 67 | tsFormatter.get().format(timestamp), 68 | level.toString(), 69 | threadName, 70 | loggerName, 71 | message); 72 | 73 | } else { 74 | System.out.printf("%s|%s|%s|%s|%s|%s%n", 75 | tsFormatter.get().format(timestamp), 76 | level.toString(), 77 | threadName, 78 | loggerName, 79 | message, 80 | throwable.toString()); 81 | } 82 | return; 83 | } 84 | REENTRANCY_FLAG.set(true); 85 | try (ExcerptAppender appender = cq.createAppender(); 86 | final DocumentContext dc = appender.writingDocument()) { 87 | Wire wire = dc.wire(); 88 | assert wire != null; 89 | wire 90 | .write("ts").int64(timestamp) 91 | .write("level").asEnum(level) 92 | .write("threadName").text(threadName) 93 | .write("loggerName").text(loggerName) 94 | .write("message").text(message); 95 | 96 | if (throwable != null) { 97 | wire.write("throwable").throwable(throwable); 98 | } 99 | 100 | if (args != null && args.length > 0) { 101 | wire.write("args").sequence(vo -> { 102 | for (Object o : args) 103 | try { 104 | vo.object(o); 105 | } catch (IllegalArgumentException unsupported) { 106 | vo.text(o.toString()); 107 | } 108 | }); 109 | } 110 | } finally { 111 | REENTRANCY_FLAG.set(false); 112 | } 113 | } 114 | 115 | public WireType getWireType() { 116 | return cq.wireType(); 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /logger-core/src/main/java/net/openhft/chronicle/logger/LogAppenderConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger; 19 | 20 | import net.openhft.chronicle.queue.ChronicleQueue; 21 | import net.openhft.chronicle.queue.RollCycles; 22 | import net.openhft.chronicle.queue.impl.single.SingleChronicleQueueBuilder; 23 | import net.openhft.chronicle.wire.WireType; 24 | import org.jetbrains.annotations.NotNull; 25 | import org.jetbrains.annotations.Nullable; 26 | 27 | import java.beans.PropertyDescriptor; 28 | import java.lang.reflect.Method; 29 | import java.util.Map; 30 | import java.util.Properties; 31 | 32 | public class LogAppenderConfig { 33 | 34 | private static final String[] KEYS = new String[]{ 35 | "blockSize", 36 | "bufferCapacity", 37 | "rollCycle" 38 | }; 39 | 40 | private int blockSize; 41 | private long bufferCapacity; 42 | private String rollCycle; 43 | 44 | public LogAppenderConfig() { 45 | } 46 | 47 | // ************************************************************************* 48 | // 49 | // ************************************************************************* 50 | 51 | public int getBlockSize() { 52 | return this.blockSize; 53 | } 54 | 55 | public void setBlockSize(int blockSize) { 56 | this.blockSize = blockSize; 57 | } 58 | 59 | public long getBufferCapacity() { 60 | return this.bufferCapacity; 61 | } 62 | 63 | public void setBufferCapacity(long bufferCapacity) { 64 | this.bufferCapacity = bufferCapacity; 65 | } 66 | 67 | public String getRollCycle() { 68 | return rollCycle; 69 | } 70 | 71 | public void setRollCycle(String rollCycle) { 72 | this.rollCycle = rollCycle; 73 | } 74 | 75 | // ************************************************************************* 76 | // 77 | // ************************************************************************* 78 | 79 | public String[] keys() { 80 | return KEYS; 81 | } 82 | 83 | public ChronicleQueue build(String path, String wireType) { 84 | WireType wireTypeEnum = wireType != null ? WireType.valueOf(wireType.toUpperCase()) : WireType.BINARY_LIGHT; 85 | SingleChronicleQueueBuilder builder = ChronicleQueue.singleBuilder(path) 86 | .wireType(wireTypeEnum) 87 | .blockSize(blockSize) 88 | .bufferCapacity(bufferCapacity); 89 | if (rollCycle != null) 90 | builder.rollCycle(RollCycles.valueOf(rollCycle)); 91 | return builder.build(); 92 | } 93 | 94 | public void setProperties(@NotNull final Properties properties, @Nullable final String prefix) { 95 | for (final Map.Entry entry : properties.entrySet()) { 96 | final String name = entry.getKey().toString(); 97 | final String value = entry.getValue().toString(); 98 | 99 | if (prefix != null && !prefix.isEmpty()) { 100 | if (name.startsWith(prefix)) { 101 | setProperty(name.substring(prefix.length()), value); 102 | } 103 | } else { 104 | setProperty(name, value); 105 | } 106 | } 107 | } 108 | 109 | public void setProperty(@NotNull final String propName, final String propValue) { 110 | try { 111 | final PropertyDescriptor property = new PropertyDescriptor(propName, this.getClass()); 112 | final Method method = property.getWriteMethod(); 113 | final Class> type = method.getParameterTypes()[0]; 114 | 115 | if (type == null || propValue == null || propValue.isEmpty()) { 116 | return; 117 | } 118 | if (type == int.class) { 119 | method.invoke(this, Integer.parseInt(propValue)); 120 | 121 | } else if (type == long.class) { 122 | method.invoke(this, Long.parseLong(propValue)); 123 | 124 | } else if (type == boolean.class) { 125 | method.invoke(this, Boolean.parseBoolean(propValue)); 126 | 127 | } else if (type == String.class) { 128 | method.invoke(this, propValue); 129 | } 130 | } catch (Exception e) { 131 | } 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /logger-core/src/main/java/net/openhft/chronicle/logger/internal/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This package and any and all sub-packages contains strictly internal classes for this Chronicle library. 3 | * Internal classes shall never be used directly. 4 | * 5 | * Specifically, the following actions (including, but not limited to) are not allowed 6 | * on internal classes and packages: 7 | * 8 | * Casting to 9 | * Reflection of any kind 10 | * Explicit Serialize/deserialize 11 | * 12 | * 13 | * The classes in this package and any sub-package are subject to 14 | * changes at any time for any reason. 15 | */ 16 | package net.openhft.chronicle.logger.internal; 17 | -------------------------------------------------------------------------------- /logger-core/src/test/java/net/openhft/chronicle/logger/DefaultChronicleLogWriterTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger; 19 | 20 | import net.openhft.chronicle.core.OS; 21 | import net.openhft.chronicle.core.io.IOTools; 22 | import net.openhft.chronicle.core.util.Time; 23 | import net.openhft.chronicle.queue.ChronicleQueue; 24 | import net.openhft.chronicle.queue.ExcerptTailer; 25 | import net.openhft.chronicle.wire.DocumentContext; 26 | import net.openhft.chronicle.wire.Wire; 27 | import org.junit.After; 28 | import org.junit.Before; 29 | import org.junit.Test; 30 | 31 | import java.nio.file.Files; 32 | import java.nio.file.Path; 33 | import java.nio.file.Paths; 34 | import java.util.ArrayList; 35 | import java.util.List; 36 | 37 | import static java.lang.System.currentTimeMillis; 38 | import static org.junit.Assert.*; 39 | 40 | public class DefaultChronicleLogWriterTest { 41 | 42 | String baseBath; 43 | 44 | @After 45 | public void cleanup() { 46 | IOTools.deleteDirWithFiles(this.baseBath); 47 | } 48 | 49 | @Before 50 | public void setUp() throws Exception { 51 | Path path = Paths.get(OS.getTarget(), "chronicle-logger-" + Time.uniqueId()); 52 | Files.createDirectories(path); 53 | this.baseBath = path.toString(); 54 | } 55 | 56 | @Test 57 | public void testWrite() { 58 | try (final ChronicleQueue cq = ChronicleQueue.singleBuilder(this.baseBath).build()) { 59 | ChronicleLogWriter lw = new DefaultChronicleLogWriter(cq); 60 | lw.write( 61 | ChronicleLogLevel.ERROR, 62 | currentTimeMillis(), 63 | Thread.currentThread().getName(), 64 | this.getClass().getCanonicalName(), 65 | "Test message", 66 | new Exception("Test exception"), 67 | 10, 68 | 12.1 69 | ); 70 | 71 | lw.write( 72 | ChronicleLogLevel.DEBUG, 73 | currentTimeMillis(), 74 | Thread.currentThread().getName(), 75 | this.getClass().getCanonicalName(), 76 | "Test debug message" 77 | ); 78 | 79 | } 80 | 81 | try (final ChronicleQueue cq = ChronicleQueue.singleBuilder(this.baseBath).build()) { 82 | ExcerptTailer tailer = cq.createTailer(); 83 | try (DocumentContext dc = tailer.readingDocument()) { 84 | Wire wire = dc.wire(); 85 | assertNotNull(wire); 86 | assertTrue(wire.read("ts").int64() <= currentTimeMillis()); 87 | assertEquals(ChronicleLogLevel.ERROR, wire.read("level").asEnum(ChronicleLogLevel.class)); 88 | assertEquals(Thread.currentThread().getName(), wire.read("threadName").text()); 89 | assertEquals(this.getClass().getCanonicalName(), wire.read("loggerName").text()); 90 | assertEquals("Test message", wire.read("message").text()); 91 | assertEquals("Test exception", wire.read("throwable").throwable(false).getMessage()); 92 | List args = new ArrayList<>(); 93 | assertTrue(wire.hasMore()); 94 | wire.read("args").sequence(args, (l, vi) -> { 95 | while (vi.hasNextSequenceItem()) { 96 | l.add(vi.object(Object.class)); 97 | } 98 | }); 99 | assertArrayEquals(new Object[]{10, 12.1}, args.toArray(new Object[args.size()])); 100 | } 101 | 102 | try (DocumentContext dc = tailer.readingDocument()) { 103 | Wire wire = dc.wire(); 104 | assertNotNull(wire); 105 | assertTrue(wire.read("ts").int64() <= currentTimeMillis()); 106 | assertEquals(ChronicleLogLevel.DEBUG, wire.read("level").asEnum(ChronicleLogLevel.class)); 107 | assertEquals(Thread.currentThread().getName(), wire.read("threadName").text()); 108 | assertEquals(this.getClass().getCanonicalName(), wire.read("loggerName").text()); 109 | assertEquals("Test debug message", wire.read("message").text()); 110 | assertFalse(wire.hasMore()); 111 | } 112 | try (DocumentContext dc = tailer.readingDocument()) { 113 | Wire wire = dc.wire(); 114 | assertNull(wire); 115 | } 116 | } 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /logger-jcl/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 22 | 23 | 4.0.0 24 | 25 | 26 | net.openhft 27 | chronicle-logger 28 | 4.27ea2-SNAPSHOT 29 | ../pom.xml 30 | 31 | 32 | OpenHFT/Chronicle-Logger/logger-jcl 33 | chronicle-logger-jcl 34 | bundle 35 | 36 | 37 | 38 | net.openhft 39 | chronicle-logger-core 40 | 41 | 42 | 43 | 44 | commons-logging 45 | commons-logging 46 | 47 | 48 | 49 | 50 | org.slf4j 51 | slf4j-api 52 | test 53 | 54 | 55 | org.slf4j 56 | slf4j-nop 57 | test 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | org.apache.maven.plugins 66 | maven-surefire-plugin 67 | 68 | 69 | ${project.build.directory} 70 | 71 | STDOUT 72 | 73 | 74 | 75 | **/*PerfTest.java 76 | 77 | 78 | 79 | 87 | 88 | org.apache.servicemix.tooling 89 | depends-maven-plugin 90 | 91 | 92 | generate-depends-file 93 | 94 | generate-depends-file 95 | 96 | 97 | 98 | 99 | 100 | org.apache.felix 101 | maven-bundle-plugin 102 | true 103 | 104 | 105 | ${project.groupId}.${project.artifactId} 106 | OpenHFT :: ${project.artifactId} 107 | ${project.version} 108 | net.openhft.chronicle.logger.jcl.* 109 | 110 | 111 | 112 | 116 | 117 | 118 | manifest 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 128 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 129 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 130 | master 131 | 132 | 133 | 134 | -------------------------------------------------------------------------------- /logger-jcl/src/main/java/net/openhft/chronicle/logger/jcl/ChronicleLoggerFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.jcl; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogConfig; 21 | import net.openhft.chronicle.logger.ChronicleLogLevel; 22 | import net.openhft.chronicle.logger.ChronicleLogManager; 23 | import org.apache.commons.logging.Log; 24 | import org.apache.commons.logging.LogConfigurationException; 25 | import org.apache.commons.logging.LogFactory; 26 | import org.apache.commons.logging.impl.NoOpLog; 27 | 28 | import java.io.IOException; 29 | import java.util.Map; 30 | import java.util.concurrent.ConcurrentHashMap; 31 | 32 | public class ChronicleLoggerFactory extends LogFactory { 33 | private static final Log NOP_LOGGER = new NoOpLog(); 34 | 35 | private final Map loggers; 36 | private final ChronicleLogManager manager; 37 | 38 | public ChronicleLoggerFactory() { 39 | logRawDiagnostic("[CHRONICLE] Initialize ChronicleLoggerFactory"); 40 | 41 | this.loggers = new ConcurrentHashMap<>(); 42 | this.manager = ChronicleLogManager.getInstance(); 43 | 44 | logRawDiagnostic("[CHRONICLE] ChronicleLoggerFactory initialized"); 45 | } 46 | 47 | @Override 48 | public void release() { 49 | this.loggers.clear(); 50 | this.manager.clear(); 51 | } 52 | 53 | @Override 54 | public Object getAttribute(String s) { 55 | return null; 56 | } 57 | 58 | @Override 59 | public void setAttribute(String s, Object o) { 60 | } 61 | 62 | @Override 63 | public String[] getAttributeNames() { 64 | return new String[0]; 65 | } 66 | 67 | @Override 68 | public void removeAttribute(String s) { 69 | } 70 | 71 | @SuppressWarnings("rawtypes") 72 | @Override 73 | public Log getInstance(Class type) throws LogConfigurationException { 74 | return getInstance(type.getName()); 75 | } 76 | 77 | @Override 78 | public Log getInstance(String name) throws LogConfigurationException { 79 | try { 80 | return getLogger(name); 81 | } catch (Exception e) { 82 | System.err.println("Unable to initialise chronicle-jcl (" + name + ")\n " + e.getMessage()); 83 | } 84 | 85 | return NOP_LOGGER; 86 | } 87 | 88 | // ************************************************************************* 89 | // 90 | // ************************************************************************* 91 | 92 | private synchronized Log getLogger(String name) throws IOException { 93 | ChronicleLogger logger = loggers.get(name); 94 | if (logger == null) { 95 | loggers.put( 96 | name, 97 | logger = new ChronicleLogger( 98 | manager.getWriter(name), 99 | name, 100 | ChronicleLogLevel.fromStringLevel( 101 | manager.cfg().getString(name, ChronicleLogConfig.KEY_LEVEL) 102 | ) 103 | ) 104 | ); 105 | } 106 | 107 | return logger; 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /logger-jcl/src/main/java/net/openhft/chronicle/logger/jcl/internal/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This package and any and all sub-packages contains strictly internal classes for this Chronicle library. 3 | * Internal classes shall never be used directly. 4 | * 5 | * Specifically, the following actions (including, but not limited to) are not allowed 6 | * on internal classes and packages: 7 | * 8 | * Casting to 9 | * Reflection of any kind 10 | * Explicit Serialize/deserialize 11 | * 12 | * 13 | * The classes in this package and any sub-package are subject to 14 | * changes at any time for any reason. 15 | */ 16 | package net.openhft.chronicle.logger.jcl.internal; 17 | -------------------------------------------------------------------------------- /logger-jcl/src/main/resources/META-INF/services/org.apache.commons.logging.LogFactory: -------------------------------------------------------------------------------- 1 | net.openhft.chronicle.logger.jcl.ChronicleLoggerFactory -------------------------------------------------------------------------------- /logger-jcl/src/test/java/net/openhft/chronicle/logger/jcl/JclTestBase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.jcl; 19 | 20 | import net.openhft.chronicle.core.OS; 21 | import net.openhft.chronicle.core.util.Time; 22 | import net.openhft.chronicle.logger.ChronicleLogLevel; 23 | import org.apache.commons.logging.Log; 24 | 25 | class JclTestBase { 26 | 27 | // ************************************************************************* 28 | // 29 | // ************************************************************************* 30 | 31 | static final ChronicleLogLevel[] LOG_LEVELS = ChronicleLogLevel.values(); 32 | 33 | static String basePath() { 34 | String path = System.getProperty("java.io.tmpdir"); 35 | String sep = System.getProperty("file.separator"); 36 | 37 | if (!path.endsWith(sep)) { 38 | path += sep; 39 | } 40 | 41 | return path + "chronicle-jcl"; 42 | } 43 | 44 | static String basePath(String loggerName) { 45 | return basePath() + System.getProperty("file.separator") + loggerName; 46 | } 47 | 48 | static void log(Log logger, ChronicleLogLevel level, String message) { 49 | switch (level) { 50 | case TRACE: 51 | logger.trace(message); 52 | break; 53 | 54 | case DEBUG: 55 | logger.debug(message); 56 | break; 57 | 58 | case INFO: 59 | logger.info(message); 60 | break; 61 | 62 | case WARN: 63 | logger.warn(message); 64 | break; 65 | 66 | case ERROR: 67 | logger.error(message); 68 | break; 69 | default: 70 | throw new UnsupportedOperationException(); 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /logger-jcl/src/test/resources/chronicle.logger.properties: -------------------------------------------------------------------------------- 1 | 2 | # 3 | # Copyright (C) 2014-2017 Chronicle Software 4 | # 5 | # https://chronicle.software 6 | # 7 | # This program is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU Lesser General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License. 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 14 | # GNU 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, see . 18 | # 19 | 20 | ################################################################################ 21 | # Common 22 | ################################################################################ 23 | 24 | chronicle.logger.base = ${java.io.tmpdir}/chronicle-jcl 25 | chronicle.logger.root.path = ${chronicle.logger.base}/root 26 | chronicle.logger.root.level = debug 27 | chronicle.logger.root.append = false 28 | 29 | ################################################################################ 30 | # Loggers 31 | ################################################################################ 32 | 33 | # logger : Logger1 34 | chronicle.logger.logger_1.path = ${chronicle.logger.base}/logger_1 35 | chronicle.logger.logger_1.level = info 36 | chronicle.logger.logger_1.wireType = JSON 37 | 38 | # logger : impl 39 | chronicle.logger.readwrite.path = ${chronicle.logger.base}/readwrite 40 | -------------------------------------------------------------------------------- /logger-jul/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 22 | 23 | 4.0.0 24 | 25 | 26 | net.openhft 27 | chronicle-logger 28 | 4.27ea2-SNAPSHOT 29 | ../pom.xml 30 | 31 | 32 | OpenHFT/Chronicle-Logger/logger-jul 33 | chronicle-logger-jul 34 | bundle 35 | 36 | 37 | 38 | net.openhft 39 | chronicle-logger-core 40 | 41 | 42 | org.slf4j 43 | slf4j-nop 44 | test 45 | 46 | 47 | 48 | 49 | 50 | 51 | org.apache.maven.plugins 52 | maven-surefire-plugin 53 | 54 | 1 55 | false 56 | 57 | **/*PerfTest.java 58 | 59 | 60 | ${project.build.directory} 61 | 62 | ${project.basedir}/src/test/resources 63 | 64 | 65 | 66 | 67 | 75 | 76 | org.apache.servicemix.tooling 77 | depends-maven-plugin 78 | 79 | 80 | generate-depends-file 81 | 82 | generate-depends-file 83 | 84 | 85 | 86 | 87 | 88 | org.apache.felix 89 | maven-bundle-plugin 90 | true 91 | 92 | 93 | ${project.groupId}.${project.artifactId} 94 | OpenHFT :: ${project.artifactId} 95 | ${project.version} 96 | net.openhft.chronicle.logger.jul.* 97 | 98 | 99 | 100 | 104 | 105 | 106 | manifest 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 115 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 116 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 117 | master 118 | 119 | 120 | -------------------------------------------------------------------------------- /logger-jul/src/main/java/net/openhft/chronicle/logger/jul/AbstractChronicleHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.jul; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogWriter; 21 | 22 | import java.io.IOException; 23 | import java.util.logging.Filter; 24 | import java.util.logging.Handler; 25 | import java.util.logging.Level; 26 | import java.util.logging.LogRecord; 27 | 28 | abstract class AbstractChronicleHandler extends Handler { 29 | 30 | private String path; 31 | private ChronicleLogWriter writer; 32 | 33 | protected AbstractChronicleHandler() { 34 | this.path = null; 35 | this.writer = null; 36 | } 37 | 38 | @Override 39 | public void flush() { 40 | } 41 | 42 | @Override 43 | public void close() throws SecurityException { 44 | if (this.writer != null) { 45 | try { 46 | this.writer.close(); 47 | } catch (IOException e) { 48 | // Ignore 49 | } 50 | } 51 | } 52 | 53 | @Override 54 | public void publish(final LogRecord record) { 55 | if ((writer != null) && isLoggable(record)) { 56 | doPublish(record, this.writer); 57 | } 58 | } 59 | 60 | // ************************************************************************* 61 | // 62 | // ************************************************************************* 63 | 64 | protected abstract void doPublish(final LogRecord record, final ChronicleLogWriter writer); 65 | 66 | protected final void setWriter(ChronicleLogWriter appender) { 67 | this.writer = appender; 68 | } 69 | 70 | @Override 71 | public final void setFilter(Filter newFilter) { 72 | super.setFilter(newFilter); 73 | } 74 | 75 | @Override 76 | public final synchronized void setLevel(Level newLevel) { 77 | super.setLevel(newLevel); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /logger-jul/src/main/java/net/openhft/chronicle/logger/jul/ChronicleHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.jul; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogWriter; 21 | import net.openhft.chronicle.logger.DefaultChronicleLogWriter; 22 | import net.openhft.chronicle.logger.LogAppenderConfig; 23 | 24 | import java.io.IOException; 25 | import java.util.logging.Level; 26 | import java.util.logging.LogRecord; 27 | 28 | import static net.openhft.chronicle.logger.ChronicleLogConfig.KEY_WIRETYPE; 29 | 30 | public class ChronicleHandler extends AbstractChronicleHandler { 31 | 32 | @SuppressWarnings("this-escape") 33 | public ChronicleHandler() throws IOException { 34 | ChronicleHandlerConfig handlerCfg = new ChronicleHandlerConfig(getClass()); 35 | String appenderPath = handlerCfg.getString("path", null); 36 | LogAppenderConfig appenderCfg = handlerCfg.getAppenderConfig(); 37 | 38 | setLevel(handlerCfg.getLevel("level", Level.ALL)); 39 | setFilter(handlerCfg.getFilter("filter", null)); 40 | 41 | setWriter(new DefaultChronicleLogWriter(appenderCfg.build( 42 | appenderPath, 43 | handlerCfg.getStringProperty(KEY_WIRETYPE, "BINARY_LIGHT")) 44 | )); 45 | } 46 | 47 | @SuppressWarnings("deprecation") 48 | @Override 49 | protected void doPublish(final LogRecord record, final ChronicleLogWriter writer) { 50 | writer.write( 51 | ChronicleHelper.getLogLevel(record), 52 | record.getMillis(), 53 | "thread-" + record.getThreadID(), 54 | record.getLoggerName(), 55 | record.getMessage(), 56 | record.getThrown(), 57 | record.getParameters()); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /logger-jul/src/main/java/net/openhft/chronicle/logger/jul/ChronicleHelper.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.jul; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogLevel; 21 | 22 | import java.util.HashMap; 23 | import java.util.Map; 24 | import java.util.logging.Level; 25 | import java.util.logging.LogRecord; 26 | 27 | class ChronicleHelper { 28 | 29 | private static final Map julToCHronicleLevelMap; 30 | private static final Map chronicleToJulLevelMap; 31 | 32 | static { 33 | julToCHronicleLevelMap = new HashMap<>(); 34 | julToCHronicleLevelMap.put(Level.ALL, ChronicleLogLevel.TRACE); 35 | julToCHronicleLevelMap.put(Level.FINEST, ChronicleLogLevel.TRACE); 36 | julToCHronicleLevelMap.put(Level.FINER, ChronicleLogLevel.TRACE); 37 | julToCHronicleLevelMap.put(Level.FINE, ChronicleLogLevel.DEBUG); 38 | julToCHronicleLevelMap.put(Level.CONFIG, ChronicleLogLevel.DEBUG); 39 | julToCHronicleLevelMap.put(Level.INFO, ChronicleLogLevel.INFO); 40 | julToCHronicleLevelMap.put(Level.WARNING, ChronicleLogLevel.WARN); 41 | julToCHronicleLevelMap.put(Level.SEVERE, ChronicleLogLevel.ERROR); 42 | 43 | chronicleToJulLevelMap = new HashMap<>(); 44 | chronicleToJulLevelMap.put(ChronicleLogLevel.TRACE, Level.FINER); 45 | chronicleToJulLevelMap.put(ChronicleLogLevel.DEBUG, Level.FINE); 46 | chronicleToJulLevelMap.put(ChronicleLogLevel.INFO, Level.INFO); 47 | chronicleToJulLevelMap.put(ChronicleLogLevel.WARN, Level.WARNING); 48 | chronicleToJulLevelMap.put(ChronicleLogLevel.ERROR, Level.SEVERE); 49 | } 50 | 51 | private ChronicleHelper() { 52 | 53 | } 54 | 55 | static ChronicleLogLevel getLogLevel(final LogRecord julRecord) { 56 | return getLogLevel(julRecord.getLevel()); 57 | } 58 | 59 | static ChronicleLogLevel getLogLevel(final Level julLevel) { 60 | ChronicleLogLevel level = julToCHronicleLevelMap.get(julLevel); 61 | return level != null ? level : ChronicleLogLevel.DEBUG; 62 | } 63 | 64 | static Level getLogLevel(final ChronicleLogLevel chronicleLevel) { 65 | Level level = chronicleToJulLevelMap.get(chronicleLevel); 66 | return level != null ? level : Level.FINE; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /logger-jul/src/main/java/net/openhft/chronicle/logger/jul/ChronicleLoggerManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.jul; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogManager; 21 | import net.openhft.chronicle.logger.ChronicleLogWriter; 22 | 23 | import java.io.IOException; 24 | import java.util.Collections; 25 | import java.util.Enumeration; 26 | import java.util.Map; 27 | import java.util.concurrent.ConcurrentHashMap; 28 | import java.util.logging.LogManager; 29 | import java.util.logging.Logger; 30 | 31 | public class ChronicleLoggerManager extends LogManager { 32 | 33 | private final Map loggers; 34 | private final ChronicleLogManager manager; 35 | 36 | public ChronicleLoggerManager() { 37 | this.loggers = new ConcurrentHashMap<>(); 38 | this.manager = ChronicleLogManager.getInstance(); 39 | } 40 | 41 | @Override 42 | public boolean addLogger(final Logger logger) { 43 | return false; 44 | } 45 | 46 | @Override 47 | public Logger getLogger(final String name) { 48 | try { 49 | return doGetLogger(name); 50 | } catch (Exception e) { 51 | System.err.println("Unable to initialize chronicle-logger-jul (" + name + ")\n " + e.getMessage()); 52 | } 53 | 54 | return ChronicleLogger.Null.INSTANCE; 55 | } 56 | 57 | @Override 58 | public Enumeration getLoggerNames() { 59 | return Collections.enumeration(this.loggers.keySet()); 60 | } 61 | 62 | @Override 63 | public void reset() throws SecurityException { 64 | this.loggers.clear(); 65 | this.manager.clear(); 66 | } 67 | 68 | // ************************************************************************* 69 | // 70 | // ************************************************************************* 71 | 72 | private synchronized Logger doGetLogger(String name) throws IOException { 73 | Logger logger = loggers.get(name); 74 | if (logger == null) { 75 | final ChronicleLogWriter writer = manager.getWriter(name); 76 | logger = new ChronicleLogger( 77 | writer, 78 | name, 79 | manager.cfg().getLevel(name)); 80 | loggers.put(name, logger); 81 | } 82 | 83 | return logger; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /logger-jul/src/main/java/net/openhft/chronicle/logger/jul/internal/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This package and any and all sub-packages contains strictly internal classes for this Chronicle library. 3 | * Internal classes shall never be used directly. 4 | * 5 | * Specifically, the following actions (including, but not limited to) are not allowed 6 | * on internal classes and packages: 7 | * 8 | * Casting to 9 | * Reflection of any kind 10 | * Explicit Serialize/deserialize 11 | * 12 | * 13 | * The classes in this package and any sub-package are subject to 14 | * changes at any time for any reason. 15 | */ 16 | package net.openhft.chronicle.logger.jul.internal; 17 | -------------------------------------------------------------------------------- /logger-jul/src/test/java/net/openhft/chronicle/logger/jul/JulHandlerTestBase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.jul; 19 | 20 | import net.openhft.chronicle.core.OS; 21 | import net.openhft.chronicle.core.util.Time; 22 | 23 | import java.io.File; 24 | import java.io.FileInputStream; 25 | import java.io.IOException; 26 | import java.util.logging.LogManager; 27 | 28 | import static org.junit.Assert.assertNotNull; 29 | import static org.junit.Assert.assertTrue; 30 | 31 | public class JulHandlerTestBase extends JulTestBase { 32 | 33 | // ************************************************************************* 34 | // 35 | // ************************************************************************* 36 | 37 | protected static String rootPath() { 38 | String path = System.getProperty("java.io.tmpdir"); 39 | String sep = System.getProperty("file.separator"); 40 | 41 | if (!path.endsWith(sep)) { 42 | path += sep; 43 | } 44 | 45 | return path + "chronicle-jul"; 46 | } 47 | 48 | protected static String basePath(String type) { 49 | return rootPath() 50 | + System.getProperty("file.separator") 51 | + type; 52 | } 53 | 54 | /** 55 | * @param id the id of the logger 56 | * @throws IOException if an I/O error occurs 57 | */ 58 | protected void setupLogManager(String id) throws IOException { 59 | String cfgPath = System.getProperty("resources.path"); 60 | File cfgFile = new File(cfgPath, id + ".properties"); 61 | 62 | assertNotNull(cfgPath); 63 | assertTrue(cfgFile.exists()); 64 | 65 | LogManager manager = LogManager.getLogManager(); 66 | manager.reset(); 67 | manager.readConfiguration(new FileInputStream(cfgFile)); 68 | } 69 | 70 | // ************************************************************************* 71 | // 72 | // ************************************************************************* 73 | 74 | } 75 | -------------------------------------------------------------------------------- /logger-jul/src/test/java/net/openhft/chronicle/logger/jul/JulLoggerTestBase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.jul; 19 | 20 | import net.openhft.chronicle.core.OS; 21 | import net.openhft.chronicle.core.util.Time; 22 | 23 | import java.util.logging.LogManager; 24 | 25 | class JulLoggerTestBase extends JulTestBase { 26 | 27 | // ************************************************************************* 28 | // 29 | // ************************************************************************* 30 | 31 | static String basePath() { 32 | String path = System.getProperty("java.io.tmpdir"); 33 | String sep = System.getProperty("file.separator"); 34 | 35 | if (!path.endsWith(sep)) { 36 | path += sep; 37 | } 38 | 39 | return path + "chronicle-jul-api"; 40 | } 41 | 42 | static String basePath(String loggerName) { 43 | return basePath() 44 | + System.getProperty("file.separator") 45 | + loggerName; 46 | } 47 | 48 | // ************************************************************************* 49 | // 50 | // ************************************************************************* 51 | 52 | static void setupLogger(Class> testName) { 53 | setupLogger(testName.getSimpleName()); 54 | } 55 | 56 | static void setupLogger(String id) { 57 | System.setProperty( 58 | "java.util.logging.manager", 59 | ChronicleLoggerManager.class.getName()); 60 | System.setProperty( 61 | "sun.util.logging.disableCallerCheck", 62 | "false"); 63 | System.setProperty( 64 | "chronicle.logger.properties", 65 | id.endsWith(".properties") ? id : id + ".properties"); 66 | 67 | LogManager.getLogManager().reset(); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /logger-jul/src/test/java/net/openhft/chronicle/logger/jul/JulTestBase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.jul; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogLevel; 21 | 22 | import java.util.logging.Level; 23 | import java.util.logging.Logger; 24 | 25 | public class JulTestBase { 26 | 27 | protected static final ChronicleLogLevel[] LOG_LEVELS = ChronicleLogLevel.values(); 28 | 29 | // ************************************************************************* 30 | // 31 | // ************************************************************************* 32 | 33 | protected static void log(Logger logger, ChronicleLogLevel level, String fmt, Object... args) { 34 | switch (level) { 35 | case TRACE: 36 | logger.log(Level.FINER, fmt, args); 37 | break; 38 | 39 | case DEBUG: 40 | logger.log(Level.FINE, fmt, args); 41 | break; 42 | 43 | case INFO: 44 | logger.log(Level.INFO, fmt, args); 45 | break; 46 | 47 | case WARN: 48 | logger.log(Level.WARNING, fmt, args); 49 | break; 50 | 51 | case ERROR: 52 | logger.log(Level.SEVERE, fmt, args); 53 | break; 54 | default: 55 | throw new UnsupportedOperationException(); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /logger-jul/src/test/resources/JulLoggerChronicleTest.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2014-2017 Chronicle Software 3 | # 4 | # https://chronicle.software 5 | # 6 | # This program is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License 16 | # along with this program. If not, see . 17 | # 18 | 19 | ################################################################################ 20 | # Common 21 | ################################################################################ 22 | 23 | chronicle.logger.base = ${java.io.tmpdir}/chronicle-jul-api 24 | 25 | chronicle.logger.root.path = ${chronicle.logger.base}/root-binary 26 | chronicle.logger.root.level = debug 27 | chronicle.logger.root.append = false 28 | 29 | chronicle.logger.logger_1.path = ${chronicle.logger.base}/logger_1 30 | chronicle.logger.logger_1.level = info 31 | chronicle.logger.logger_1.wireType = json 32 | 33 | chronicle.logger.logger_bin.path = ${chronicle.logger.base}/logger_bin 34 | chronicle.logger.logger_bin.level = trace 35 | -------------------------------------------------------------------------------- /logger-jul/src/test/resources/binary-cfg.properties: -------------------------------------------------------------------------------- 1 | 2 | # 3 | # Copyright (C) 2014-2017 Chronicle Software 4 | # 5 | # https://chronicle.software 6 | # 7 | # This program is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU Lesser General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License. 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 14 | # GNU 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, see . 18 | # 19 | 20 | handlers=java.util.logging.ConsoleHandler, net.openhft.chronicle.logger.jul.ChronicleHandler 21 | 22 | .level=ALL 23 | 24 | java.util.logging.ConsoleHandler.level=ALL 25 | java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter 26 | 27 | net.openhft.level=WARNING 28 | net.openhft.handlers=java.util.logging.ConsoleHandler 29 | 30 | ################################################################################ 31 | # BINARY 32 | ################################################################################ 33 | 34 | net.openhft.chronicle.logger.jul.ChronicleHandler.path = ${java.io.tmpdir}/chronicle-jul 35 | net.openhft.chronicle.logger.jul.ChronicleHandler.level = ALL 36 | 37 | binary-cfg.level=INFO 38 | binary-cfg.handlers=net.openhft.chronicle.logger.jul.ChronicleHandler 39 | binary-cfg.useParentHandlers=false 40 | -------------------------------------------------------------------------------- /logger-jul/src/test/resources/binary-chronicle.properties: -------------------------------------------------------------------------------- 1 | 2 | # 3 | # Copyright (C) 2014-2017 Chronicle Software 4 | # 5 | # https://chronicle.software 6 | # 7 | # This program is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU Lesser General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License. 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 14 | # GNU 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, see . 18 | # 19 | 20 | handlers=java.util.logging.ConsoleHandler, net.openhft.chronicle.logger.jul.ChronicleHandler 21 | 22 | .level=ALL 23 | 24 | java.util.logging.ConsoleHandler.level=ALL 25 | java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter 26 | 27 | net.openhft.level=WARNING 28 | net.openhft.handlers=java.util.logging.ConsoleHandler 29 | 30 | ################################################################################ 31 | # BINARY 32 | ################################################################################ 33 | 34 | net.openhft.chronicle.logger.jul.ChronicleHandler.path = ${java.io.tmpdir}/chronicle-jul/binary-chronicle 35 | net.openhft.chronicle.logger.jul.ChronicleHandler.level = ALL 36 | 37 | binary-chronicle.level=ALL 38 | binary-chronicle.handlers=net.openhft.chronicle.logger.jul.ChronicleHandler 39 | binary-chronicle.useParentHandlers=false 40 | 41 | -------------------------------------------------------------------------------- /logger-log4j-1/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 22 | 23 | 4.0.0 24 | 25 | 26 | net.openhft 27 | chronicle-logger 28 | 4.27ea2-SNAPSHOT 29 | ../pom.xml 30 | 31 | 32 | OpenHFT/Chronicle-Logger/logger-log4j-1 33 | chronicle-logger-log4j-1 34 | bundle 35 | 36 | 37 | 38 | net.openhft 39 | chronicle-logger-core 40 | 41 | 42 | 43 | 44 | org.slf4j 45 | slf4j-api 46 | 47 | 48 | org.slf4j 49 | slf4j-log4j12 50 | 1.7.33 51 | 52 | 53 | 54 | 55 | log4j 56 | log4j 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | org.apache.maven.plugins 65 | maven-surefire-plugin 66 | 67 | 1 68 | false 69 | 70 | **/*PerfTest.java 71 | 72 | 73 | ${project.build.directory} 74 | 75 | 76 | 77 | 85 | 86 | org.apache.servicemix.tooling 87 | depends-maven-plugin 88 | 89 | 90 | generate-depends-file 91 | 92 | generate-depends-file 93 | 94 | 95 | 96 | 97 | 98 | org.apache.felix 99 | maven-bundle-plugin 100 | true 101 | 102 | 103 | ${project.groupId}.${project.artifactId} 104 | OpenHFT :: ${project.artifactId} 105 | ${project.version} 106 | net.openhft.chronicle.logger.log4j1.* 107 | 108 | 109 | 110 | 114 | 115 | 116 | manifest 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 126 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 127 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 128 | master 129 | 130 | 131 | 132 | -------------------------------------------------------------------------------- /logger-log4j-1/src/main/java/net/openhft/chronicle/logger/log4j1/ChronicleAppender.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.log4j1; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogWriter; 21 | import net.openhft.chronicle.logger.DefaultChronicleLogWriter; 22 | import net.openhft.chronicle.logger.LogAppenderConfig; 23 | 24 | import java.io.IOException; 25 | 26 | public final class ChronicleAppender extends AbstractChronicleAppender { 27 | 28 | private final LogAppenderConfig config; 29 | 30 | public ChronicleAppender() { 31 | this.config = new LogAppenderConfig(); 32 | } 33 | 34 | // ************************************************************************* 35 | // Custom logging options 36 | // ************************************************************************* 37 | 38 | public void setBlockSize(int blockSize) { 39 | config.setBlockSize(blockSize); 40 | } 41 | 42 | public void setBufferCapacity(int bufferCapacity) { 43 | config.setBufferCapacity(bufferCapacity); 44 | } 45 | 46 | public String rollCycle() { 47 | return config.getRollCycle(); 48 | } 49 | 50 | public void rollCycle(String rollCycle) { 51 | config.setRollCycle(rollCycle); 52 | } 53 | 54 | @Override 55 | protected ChronicleLogWriter createWriter() throws IOException { 56 | return new DefaultChronicleLogWriter(this.config.build(this.getPath(), this.getWireType())); 57 | } 58 | 59 | // ************************************************************************* 60 | // LogAppenderConfig 61 | // ************************************************************************* 62 | 63 | LogAppenderConfig getChronicleConfig() { 64 | return this.config; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /logger-log4j-1/src/main/java/net/openhft/chronicle/logger/log4j1/internal/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This package and any and all sub-packages contains strictly internal classes for this Chronicle library. 3 | * Internal classes shall never be used directly. 4 | * 5 | * Specifically, the following actions (including, but not limited to) are not allowed 6 | * on internal classes and packages: 7 | * 8 | * Casting to 9 | * Reflection of any kind 10 | * Explicit Serialize/deserialize 11 | * 12 | * 13 | * The classes in this package and any sub-package are subject to 14 | * changes at any time for any reason. 15 | */ 16 | package net.openhft.chronicle.logger.log4j1.internal; 17 | -------------------------------------------------------------------------------- /logger-log4j-1/src/test/java/net/openhft/chronicle/logger/log4j1/Log4j1TestBase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.log4j1; 19 | 20 | import net.openhft.chronicle.core.OS; 21 | import net.openhft.chronicle.core.util.Time; 22 | import net.openhft.chronicle.logger.ChronicleLogLevel; 23 | import org.slf4j.Logger; 24 | 25 | import java.io.File; 26 | 27 | class Log4j1TestBase { 28 | 29 | // ************************************************************************* 30 | // 31 | // ************************************************************************* 32 | 33 | static final ChronicleLogLevel[] LOG_LEVELS = ChronicleLogLevel.values(); 34 | 35 | static String rootPath() { 36 | String path = System.getProperty("java.io.tmpdir"); 37 | String sep = System.getProperty("file.separator"); 38 | 39 | if (!path.endsWith(sep)) { 40 | path += sep; 41 | } 42 | 43 | return path + "chronicle-log4j1"; 44 | } 45 | 46 | static String basePath(String type) { 47 | return rootPath() 48 | + File.separator 49 | + type; 50 | } 51 | 52 | static void log(Logger logger, ChronicleLogLevel level, String fmt, Object... args) { 53 | switch (level) { 54 | case TRACE: 55 | logger.trace(fmt, args); 56 | break; 57 | 58 | case DEBUG: 59 | logger.debug(fmt, args); 60 | break; 61 | 62 | case INFO: 63 | logger.info(fmt, args); 64 | break; 65 | 66 | case WARN: 67 | logger.warn(fmt, args); 68 | break; 69 | 70 | case ERROR: 71 | logger.error(fmt, args); 72 | break; 73 | default: 74 | throw new UnsupportedOperationException(); 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /logger-log4j-1/src/test/resources/log4j.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /logger-log4j-2/src/main/java/net/openhft/chronicle/logger/log4j2/ChronicleAppender.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.log4j2; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogWriter; 21 | import net.openhft.chronicle.logger.DefaultChronicleLogWriter; 22 | import net.openhft.chronicle.logger.LogAppenderConfig; 23 | import org.apache.logging.log4j.core.Filter; 24 | import org.apache.logging.log4j.core.LogEvent; 25 | import org.apache.logging.log4j.core.config.plugins.Plugin; 26 | import org.apache.logging.log4j.core.config.plugins.PluginAttribute; 27 | import org.apache.logging.log4j.core.config.plugins.PluginElement; 28 | import org.apache.logging.log4j.core.config.plugins.PluginFactory; 29 | import org.jetbrains.annotations.NotNull; 30 | 31 | import java.io.IOException; 32 | 33 | @Plugin( 34 | name = "Chronicle", 35 | category = "Core", 36 | elementType = "appender", 37 | printObject = true) 38 | public class ChronicleAppender extends AbstractChronicleAppender { 39 | 40 | private final ChronicleCfg config; 41 | 42 | public ChronicleAppender(final String name, final Filter filter, final String path, final String wireType, final ChronicleCfg config) { 43 | super(name, filter, path, wireType); 44 | 45 | this.config = config != null ? config : new ChronicleCfg(); 46 | } 47 | 48 | // ************************************************************************* 49 | // 50 | // ************************************************************************* 51 | 52 | @PluginFactory 53 | public static ChronicleAppender createAppender( 54 | @PluginAttribute("name") final String name, 55 | @PluginAttribute("path") final String path, 56 | @PluginAttribute("wireType") final String wireType, 57 | @PluginElement("chronicleCfg") final ChronicleCfg chronicleConfig, 58 | @PluginElement("filter") final Filter filter) { 59 | if (name == null) { 60 | LOGGER.error("No name provided for ChronicleAppender"); 61 | return null; 62 | } 63 | 64 | if (path == null) { 65 | LOGGER.error("No path provided for ChronicleAppender"); 66 | return null; 67 | } 68 | 69 | return new ChronicleAppender(name, filter, path, wireType, chronicleConfig); 70 | } 71 | 72 | @Override 73 | public void doAppend(@NotNull final LogEvent event, @NotNull final ChronicleLogWriter writer) { 74 | writer.write( 75 | toChronicleLogLevel(event.getLevel()), 76 | event.getTimeMillis(), 77 | event.getThreadName(), 78 | event.getLoggerName(), 79 | event.getMessage().getFormattedMessage(), 80 | event.getThrown() 81 | ); 82 | } 83 | 84 | @Override 85 | protected ChronicleLogWriter createWriter() throws IOException { 86 | return new DefaultChronicleLogWriter(config.build(getPath(), getWireType())); 87 | } 88 | 89 | // ************************************************************************* 90 | // 91 | // ************************************************************************* 92 | 93 | protected LogAppenderConfig getChronicleConfig() { 94 | return this.config; 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /logger-log4j-2/src/main/java/net/openhft/chronicle/logger/log4j2/internal/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This package and any and all sub-packages contains strictly internal classes for this Chronicle library. 3 | * Internal classes shall never be used directly. 4 | * 5 | * Specifically, the following actions (including, but not limited to) are not allowed 6 | * on internal classes and packages: 7 | * 8 | * Casting to 9 | * Reflection of any kind 10 | * Explicit Serialize/deserialize 11 | * 12 | * 13 | * The classes in this package and any sub-package are subject to 14 | * changes at any time for any reason. 15 | */ 16 | package net.openhft.chronicle.logger.log4j2.internal; 17 | -------------------------------------------------------------------------------- /logger-log4j-2/src/test/java/net/openhft/chronicle/logger/log4j2/Log4j2TestBase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.log4j2; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogLevel; 21 | import org.apache.logging.log4j.LogManager; 22 | import org.slf4j.Logger; 23 | 24 | import java.io.File; 25 | 26 | public class Log4j2TestBase { 27 | 28 | // ************************************************************************* 29 | // 30 | // ************************************************************************* 31 | 32 | static final ChronicleLogLevel[] LOG_LEVELS = ChronicleLogLevel.values(); 33 | 34 | static String rootPath() { 35 | String path = System.getProperty("java.io.tmpdir"); 36 | String sep = System.getProperty("file.separator"); 37 | 38 | if (!path.endsWith(sep)) { 39 | path += sep; 40 | } 41 | 42 | return path + "chronicle-log4j2"; 43 | } 44 | 45 | static String basePath(String type) { 46 | return rootPath() 47 | + File.separator 48 | + type; 49 | } 50 | 51 | static void log(Logger logger, ChronicleLogLevel level, String fmt, Object... args) { 52 | switch (level) { 53 | case TRACE: 54 | logger.trace(fmt, args); 55 | break; 56 | 57 | case DEBUG: 58 | logger.debug(fmt, args); 59 | break; 60 | 61 | case INFO: 62 | logger.info(fmt, args); 63 | break; 64 | 65 | case WARN: 66 | logger.warn(fmt, args); 67 | break; 68 | 69 | case ERROR: 70 | logger.error(fmt, args); 71 | break; 72 | default: 73 | throw new UnsupportedOperationException(); 74 | } 75 | } 76 | 77 | // ************************************************************************* 78 | // 79 | // ************************************************************************* 80 | 81 | static org.apache.logging.log4j.core.Appender getAppender(String name) { 82 | final org.apache.logging.log4j.core.LoggerContext ctx = 83 | (org.apache.logging.log4j.core.LoggerContext) LogManager.getContext(); 84 | 85 | return ctx.getConfiguration().getAppender(name); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /logger-log4j-2/src/test/java/net/openhft/chronicle/logger/log4j2/Log4j2VulnerabilityTest.java: -------------------------------------------------------------------------------- 1 | package net.openhft.chronicle.logger.log4j2; 2 | 3 | import org.apache.logging.log4j.LogManager; 4 | import org.junit.BeforeClass; 5 | import org.junit.Test; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | 9 | import java.io.IOException; 10 | import java.nio.file.Files; 11 | import java.nio.file.Paths; 12 | 13 | /** 14 | * see https://blog.cloudflare.com/inside-the-log4j2-vulnerability-cve-2021-44228/ etc. 15 | * 16 | * This is not a proper unit test - just some exploratory code 17 | */ 18 | public class Log4j2VulnerabilityTest extends Log4j2TestBase { 19 | 20 | public static final String VULNERABILITY = "${jndi:ldap://localhost/xxxx}"; 21 | 22 | @BeforeClass 23 | public static void systemProperties() { 24 | System.setProperty("com.sun.jndi.rmi.object.trustURLCodebase", "true"); 25 | } 26 | 27 | /** 28 | * Run this test with -Dlog4j2.debug and you will not see any JNDI-related logging - see below 29 | */ 30 | @Test 31 | public void testVulnerability() throws IOException { 32 | final String testId = "chronicle"; 33 | final String threadId = testId + "-th"; 34 | final Logger logger = LoggerFactory.getLogger(testId); 35 | 36 | Thread.currentThread().setName(threadId); 37 | Files.createDirectories(Paths.get(basePath(testId))); 38 | 39 | logger.error(VULNERABILITY); 40 | } 41 | 42 | /** 43 | * Run this test with -Dlog4j2.debug and you will see 44 | * 45 | * {@code WARN StatusLogger Error looking up JNDI resource [ldap://localhost/xxxx]} 46 | * 47 | */ 48 | @Test 49 | public void testVulnerabilityLog4j2() { 50 | LogManager.getLogger("HelloWorld").error(VULNERABILITY); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /logger-log4j-2/src/test/resources/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | ${sys:java.io.tmpdir}/chronicle-log4j2/conf-chronicle 34 | 35 | 128 36 | 256 37 | 38 | 39 | 40 | 41 | ${sys:java.io.tmpdir}/chronicle-log4j2/chronicle 42 | 43 | FAST_HOURLY 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /logger-logback/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 22 | 23 | 4.0.0 24 | 25 | 26 | net.openhft 27 | chronicle-logger 28 | 4.27ea2-SNAPSHOT 29 | ../pom.xml 30 | 31 | 32 | OpenHFT/Chronicle-Logger/logger-logback 33 | chronicle-logger-logback 34 | bundle 35 | 36 | 37 | 38 | net.openhft 39 | chronicle-logger-core 40 | 41 | 42 | 43 | 44 | org.slf4j 45 | slf4j-api 46 | 47 | 48 | 49 | 50 | ch.qos.logback 51 | logback-classic 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | org.apache.maven.plugins 60 | maven-surefire-plugin 61 | 62 | 1 63 | false 64 | 65 | **/*PerfTest.java 66 | 67 | 68 | 69 | ${project.basedir}/src/test/resources 70 | 71 | ${project.build.directory} 72 | 73 | 74 | 75 | 83 | 84 | org.apache.servicemix.tooling 85 | depends-maven-plugin 86 | 87 | 88 | generate-depends-file 89 | 90 | generate-depends-file 91 | 92 | 93 | 94 | 95 | 96 | org.apache.felix 97 | maven-bundle-plugin 98 | true 99 | 100 | 101 | ${project.groupId}.${project.artifactId} 102 | OpenHFT :: ${project.artifactId} 103 | ${project.version} 104 | net.openhft.chronicle.logger.logback.* 105 | 106 | 107 | 108 | 112 | 113 | 114 | manifest 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 123 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 124 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 125 | master 126 | 127 | 128 | -------------------------------------------------------------------------------- /logger-logback/src/main/java/net/openhft/chronicle/logger/logback/AbstractChronicleAppender.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.logback; 19 | 20 | import ch.qos.logback.classic.Level; 21 | import ch.qos.logback.classic.spi.ILoggingEvent; 22 | import ch.qos.logback.core.Appender; 23 | import ch.qos.logback.core.filter.Filter; 24 | import ch.qos.logback.core.spi.ContextAwareBase; 25 | import ch.qos.logback.core.spi.FilterAttachableImpl; 26 | import ch.qos.logback.core.spi.FilterReply; 27 | import net.openhft.chronicle.logger.ChronicleLogLevel; 28 | import net.openhft.chronicle.logger.ChronicleLogWriter; 29 | 30 | import java.io.IOException; 31 | import java.util.List; 32 | 33 | public abstract class AbstractChronicleAppender 34 | extends ContextAwareBase 35 | implements Appender { 36 | 37 | private final FilterAttachableImpl filterAttachable; 38 | protected ChronicleLogWriter writer; 39 | private String name; 40 | private boolean started; 41 | private String path; 42 | private String wireType; 43 | 44 | protected AbstractChronicleAppender() { 45 | this.filterAttachable = new FilterAttachableImpl<>(); 46 | this.name = null; 47 | this.started = false; 48 | this.path = null; 49 | this.wireType = null; 50 | this.writer = null; 51 | } 52 | 53 | // ************************************************************************* 54 | // Custom logging options 55 | // ************************************************************************* 56 | 57 | public static ChronicleLogLevel toChronicleLogLevel(final Level level) { 58 | switch (level.levelInt) { 59 | case Level.DEBUG_INT: 60 | return ChronicleLogLevel.DEBUG; 61 | case Level.TRACE_INT: 62 | return ChronicleLogLevel.TRACE; 63 | case Level.INFO_INT: 64 | return ChronicleLogLevel.INFO; 65 | case Level.WARN_INT: 66 | return ChronicleLogLevel.WARN; 67 | case Level.ERROR_INT: 68 | return ChronicleLogLevel.ERROR; 69 | default: 70 | throw new IllegalArgumentException(level.levelInt + " not a valid level value"); 71 | } 72 | } 73 | 74 | public String getPath() { 75 | return this.path; 76 | } 77 | 78 | public void setPath(String path) { 79 | this.path = path; 80 | } 81 | 82 | public String getWireType() { 83 | return wireType; 84 | } 85 | 86 | // ************************************************************************* 87 | // Chronicle implementation 88 | // ************************************************************************* 89 | 90 | public void setWireType(String wireType) { 91 | this.wireType = wireType; 92 | } 93 | 94 | protected abstract ChronicleLogWriter createWriter() throws IOException; 95 | 96 | // ************************************************************************* 97 | // 98 | // ************************************************************************* 99 | 100 | protected abstract void doAppend(final ILoggingEvent event, final ChronicleLogWriter writer); 101 | 102 | @Override 103 | public String getName() { 104 | return name; 105 | } 106 | 107 | @Override 108 | public void setName(String name) { 109 | this.name = name; 110 | } 111 | 112 | @Override 113 | public boolean isStarted() { 114 | return started; 115 | } 116 | 117 | @Override 118 | public void addFilter(Filter newFilter) { 119 | this.filterAttachable.addFilter(newFilter); 120 | } 121 | 122 | @Override 123 | public void clearAllFilters() { 124 | this.filterAttachable.clearAllFilters(); 125 | } 126 | 127 | @Override 128 | public List> getCopyOfAttachedFiltersList() { 129 | return this.filterAttachable.getCopyOfAttachedFiltersList(); 130 | } 131 | 132 | @Override 133 | public FilterReply getFilterChainDecision(ILoggingEvent event) { 134 | return this.filterAttachable.getFilterChainDecision(event); 135 | } 136 | 137 | @Override 138 | public void start() { 139 | if (getPath() == null) { 140 | addError("Appender " + getName() + " has configuration errors and is not started!"); 141 | 142 | } else { 143 | try { 144 | this.writer = createWriter(); 145 | this.started = true; 146 | } catch (IOException e) { 147 | this.writer = null; 148 | addError("Appender " + getName() + " " + e.getMessage()); 149 | } 150 | } 151 | } 152 | 153 | @Override 154 | public void stop() { 155 | if (this.writer != null) { 156 | try { 157 | this.writer.close(); 158 | } catch (IOException e) { 159 | addError("Appender " + getName() + " " + e.getMessage()); 160 | } 161 | } 162 | 163 | this.started = false; 164 | } 165 | 166 | // ************************************************************************* 167 | // 168 | // ************************************************************************* 169 | 170 | @Override 171 | public void doAppend(final ILoggingEvent event) { 172 | if (getFilterChainDecision(event) != FilterReply.DENY) { 173 | doAppend(event, writer); 174 | } 175 | } 176 | } 177 | -------------------------------------------------------------------------------- /logger-logback/src/main/java/net/openhft/chronicle/logger/logback/ChronicleAppender.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.logback; 19 | 20 | import ch.qos.logback.classic.spi.ILoggingEvent; 21 | import ch.qos.logback.classic.spi.ThrowableProxy; 22 | import ch.qos.logback.core.joran.spi.DefaultClass; 23 | import net.openhft.chronicle.logger.ChronicleLogWriter; 24 | import net.openhft.chronicle.logger.DefaultChronicleLogWriter; 25 | import net.openhft.chronicle.logger.LogAppenderConfig; 26 | 27 | import java.io.IOException; 28 | 29 | public class ChronicleAppender extends AbstractChronicleAppender { 30 | 31 | private boolean includeCallerData; 32 | private boolean includeMDC; 33 | 34 | private LogAppenderConfig config; 35 | 36 | public ChronicleAppender() { 37 | super(); 38 | 39 | this.includeCallerData = true; 40 | this.includeMDC = true; 41 | this.config = new LogAppenderConfig(); 42 | } 43 | 44 | public LogAppenderConfig getChronicleConfig() { 45 | return this.config; 46 | } 47 | 48 | @DefaultClass(value = LogAppenderConfig.class) 49 | public void setChronicleConfig(final LogAppenderConfig config) { 50 | this.config = config; 51 | } 52 | 53 | @Override 54 | protected ChronicleLogWriter createWriter() throws IOException { 55 | return new DefaultChronicleLogWriter(this.config.build(this.getPath(), getWireType())); 56 | } 57 | 58 | // ************************************************************************* 59 | // Custom logging options 60 | // ************************************************************************* 61 | 62 | public boolean isIncludeCallerData() { 63 | return this.includeCallerData; 64 | } 65 | 66 | public void setIncludeCallerData(boolean logCallerData) { 67 | this.includeCallerData = logCallerData; 68 | } 69 | 70 | public boolean isIncludeMappedDiagnosticContext() { 71 | return this.includeMDC; 72 | } 73 | 74 | public void setIncludeMappedDiagnosticContext(boolean logMDC) { 75 | this.includeMDC = logMDC; 76 | } 77 | 78 | // ************************************************************************* 79 | // 80 | // ************************************************************************* 81 | 82 | @Override 83 | public void doAppend(final ILoggingEvent event, final ChronicleLogWriter writer) { 84 | final ThrowableProxy tp = (ThrowableProxy) event.getThrowableProxy(); 85 | 86 | writer.write( 87 | toChronicleLogLevel(event.getLevel()), 88 | event.getTimeStamp(), 89 | event.getThreadName(), 90 | event.getLoggerName(), 91 | event.getMessage(), 92 | tp != null ? tp.getThrowable() : null, 93 | event.getArgumentArray() 94 | ); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /logger-logback/src/main/java/net/openhft/chronicle/logger/logback/internal/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This package and any and all sub-packages contains strictly internal classes for this Chronicle library. 3 | * Internal classes shall never be used directly. 4 | * 5 | * Specifically, the following actions (including, but not limited to) are not allowed 6 | * on internal classes and packages: 7 | * 8 | * Casting to 9 | * Reflection of any kind 10 | * Explicit Serialize/deserialize 11 | * 12 | * 13 | * The classes in this package and any sub-package are subject to 14 | * changes at any time for any reason. 15 | */ 16 | package net.openhft.chronicle.logger.logback.internal; 17 | -------------------------------------------------------------------------------- /logger-logback/src/test/java/net/openhft/chronicle/logger/logback/LogbackChronicleProgrammaticConfigTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.logback; 19 | 20 | import ch.qos.logback.classic.Logger; 21 | import ch.qos.logback.classic.LoggerContext; 22 | import net.openhft.chronicle.core.OS; 23 | import net.openhft.chronicle.core.util.Time; 24 | import net.openhft.chronicle.logger.LogAppenderConfig; 25 | import org.junit.Test; 26 | import org.slf4j.LoggerFactory; 27 | 28 | public class LogbackChronicleProgrammaticConfigTest extends LogbackTestBase { 29 | 30 | @Test 31 | public void testConfig() { 32 | LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory(); 33 | context.reset(); 34 | 35 | ChronicleAppender appender = new ChronicleAppender(); 36 | appender.setPath(OS.getTarget() + "/clog" + Time.uniqueId()); 37 | appender.setChronicleConfig(new LogAppenderConfig()); 38 | appender.setContext(context); 39 | appender.start(); 40 | 41 | Logger logger = context.getLogger(Logger.ROOT_LOGGER_NAME); 42 | logger.addAppender(appender); 43 | 44 | logger.info("Hello World"); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /logger-logback/src/test/java/net/openhft/chronicle/logger/logback/LogbackIndexedChronicleConfigTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.logback; 19 | 20 | import ch.qos.logback.classic.spi.ILoggingEvent; 21 | import org.junit.Before; 22 | import org.junit.Test; 23 | 24 | import java.io.IOException; 25 | 26 | import static org.junit.Assert.*; 27 | 28 | public class LogbackIndexedChronicleConfigTest extends LogbackTestBase { 29 | 30 | @Before 31 | public void setup() { 32 | System.setProperty( 33 | "logback.configurationFile", 34 | System.getProperty("resources.path") + "/logback-chronicle-config.xml" 35 | ); 36 | } 37 | 38 | // ************************************************************************* 39 | // 40 | // ************************************************************************* 41 | 42 | @Test 43 | public void testBinaryIndexedChronicleAppenderConfig() throws IOException { 44 | final String loggerName = "config-binary-chronicle"; 45 | final String appenderName = "CONFIG-BINARY-CHRONICLE"; 46 | 47 | final ch.qos.logback.classic.Logger logger = getLoggerContext().getLogger(loggerName); 48 | assertNotNull(logger); 49 | 50 | final ch.qos.logback.core.Appender appender = logger.getAppender(appenderName); 51 | assertNotNull(appender); 52 | assertTrue(appender instanceof ChronicleAppender); 53 | 54 | ChronicleAppender ba = (ChronicleAppender) appender; 55 | assertEquals(128, ba.getChronicleConfig().getBlockSize()); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /logger-logback/src/test/java/net/openhft/chronicle/logger/logback/LogbackTestBase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.logback; 19 | 20 | import ch.qos.logback.classic.LoggerContext; 21 | import net.openhft.chronicle.core.OS; 22 | import net.openhft.chronicle.core.util.Time; 23 | import net.openhft.chronicle.logger.ChronicleLogLevel; 24 | import org.slf4j.Logger; 25 | import org.slf4j.LoggerFactory; 26 | 27 | public class LogbackTestBase { 28 | 29 | // ************************************************************************* 30 | // 31 | // ************************************************************************* 32 | 33 | static final ChronicleLogLevel[] LOG_LEVELS = ChronicleLogLevel.values(); 34 | 35 | static String rootPath() { 36 | String path = System.getProperty("java.io.tmpdir"); 37 | String sep = System.getProperty("file.separator"); 38 | 39 | if (!path.endsWith(sep)) { 40 | path += sep; 41 | } 42 | 43 | return path + "chronicle-logback"; 44 | } 45 | 46 | static String basePath(String type) { 47 | return rootPath() 48 | + System.getProperty("file.separator") 49 | + type; 50 | } 51 | 52 | static void log(Logger logger, ChronicleLogLevel level, String fmt, Object... args) { 53 | switch (level) { 54 | case TRACE: 55 | logger.trace(fmt, args); 56 | break; 57 | 58 | case DEBUG: 59 | logger.debug(fmt, args); 60 | break; 61 | 62 | case INFO: 63 | logger.info(fmt, args); 64 | break; 65 | 66 | case WARN: 67 | logger.warn(fmt, args); 68 | break; 69 | 70 | case ERROR: 71 | logger.error(fmt, args); 72 | break; 73 | default: 74 | throw new UnsupportedOperationException(); 75 | } 76 | } 77 | 78 | // ************************************************************************* 79 | // 80 | // ************************************************************************* 81 | 82 | LoggerContext getLoggerContext() { 83 | return (LoggerContext) LoggerFactory.getILoggerFactory(); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /logger-logback/src/test/resources/logback-chronicle-binary-appender.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 22 | 23 | 25 | 26 | %d %contextName [%t] %level %logger{36} - %msg%n 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 36 | ${java.io.tmpdir}/chronicle-logback/binary-chronicle 37 | false 38 | false 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /logger-logback/src/test/resources/logback-chronicle-config.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 22 | 23 | 25 | 26 | %d %contextName [%t] %level %logger{36} - %msg%n 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 36 | ${java.io.tmpdir}/chronicle-logback/config-binary-chronicle 37 | false 38 | false 39 | 40 | 41 | 128 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /logger-slf4j-2/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 22 | 23 | 4.0.0 24 | 25 | 26 | net.openhft 27 | chronicle-logger 28 | 4.27ea2-SNAPSHOT 29 | ../pom.xml 30 | 31 | 32 | OpenHFT/Chronicle-Logger/logger-slf4j-2 33 | chronicle-logger-slf4j-2 34 | bundle 35 | 36 | 37 | 38 | net.openhft 39 | chronicle-logger-core 40 | 41 | 42 | 43 | 44 | org.slf4j 45 | slf4j-api 46 | 2.0.0 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | org.apache.maven.plugins 55 | maven-surefire-plugin 56 | 57 | 58 | **/*PerfTest.java 59 | 60 | 61 | ${project.build.directory} 62 | 63 | 64 | 65 | 73 | 74 | org.apache.servicemix.tooling 75 | depends-maven-plugin 76 | 77 | 78 | generate-depends-file 79 | 80 | generate-depends-file 81 | 82 | 83 | 84 | 85 | 86 | org.apache.felix 87 | maven-bundle-plugin 88 | true 89 | 90 | 91 | ${project.groupId}.${project.artifactId} 92 | OpenHFT :: ${project.artifactId} 93 | ${project.version} 94 | net.openhft.chronicle.logger.slf4j.* 95 | 96 | 97 | 98 | 102 | 103 | 104 | manifest 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 114 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 115 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 116 | master 117 | 118 | 119 | 120 | -------------------------------------------------------------------------------- /logger-slf4j-2/src/main/java/net/openhft/chronicle/logger/slf4j2/ChronicleLoggerFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.slf4j2; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogManager; 21 | import net.openhft.chronicle.logger.ChronicleLogWriter; 22 | import org.slf4j.ILoggerFactory; 23 | import org.slf4j.Logger; 24 | import org.slf4j.helpers.NOPLogger; 25 | import org.slf4j.impl.SimpleLogger; 26 | 27 | import java.util.Map; 28 | import java.util.concurrent.ConcurrentHashMap; 29 | 30 | /** 31 | * Simple implementation of Logger that sends all enabled slf4j messages, 32 | * for all defined loggers, to one or more VanillaChronicle.. 33 | * 34 | * To configure this sl4j binding you need to specify the location of a properties 35 | * files via system properties: 36 | * {@code -Dchronicle.logger.properties=${pathOfYourPropertiesFile}} 37 | * 38 | * The following system properties are supported to configure the behavior of this 39 | * logger: 40 | * 41 | * {@code chronicle.logger.root.path} 42 | * {@code chronicle.logger.root.level} 43 | * {@code chronicle.logger.root.append} 44 | * 45 | */ 46 | public class ChronicleLoggerFactory implements ILoggerFactory { 47 | private final Map loggers; 48 | private final ChronicleLogManager manager; 49 | 50 | // ************************************************************************* 51 | // 52 | // ************************************************************************* 53 | 54 | /** 55 | * c-tor 56 | */ 57 | public ChronicleLoggerFactory() { 58 | this.loggers = new ConcurrentHashMap<>(); 59 | this.manager = ChronicleLogManager.getInstance(); 60 | } 61 | 62 | // ************************************************************************* 63 | // for testing 64 | // ************************************************************************* 65 | 66 | /** 67 | * Return an appropriate {@link ChronicleLogger} instance by name. 68 | */ 69 | @Override 70 | public Logger getLogger(String name) { 71 | try { 72 | return doGetLogger(name); 73 | } catch (Exception e) { 74 | System.err.println("Unable to initialize chronicle-logger-slf4j (" + name + ")\n " + e.getMessage()); 75 | e.printStackTrace(); 76 | } 77 | 78 | return NOPLogger.NOP_LOGGER; 79 | } 80 | 81 | // ************************************************************************* 82 | // 83 | // ************************************************************************* 84 | 85 | synchronized void reload() { 86 | this.loggers.clear(); 87 | this.manager.reload(); 88 | } 89 | 90 | private synchronized Logger doGetLogger(String name) { 91 | Logger logger = loggers.get(name); 92 | if (logger == null) { 93 | if (name != null && name.startsWith("net.openhft")) { 94 | SimpleLogger.lazyInit(); 95 | logger = new SimpleLogger(name); 96 | } else { 97 | final ChronicleLogWriter writer = manager.getWriter(name); 98 | logger = new ChronicleLogger(writer, name, manager.cfg().getLevel(name)); 99 | } 100 | loggers.put(name, logger); 101 | } 102 | 103 | return logger; 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /logger-slf4j-2/src/main/java/net/openhft/chronicle/logger/slf4j2/internal/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This package and any and all sub-packages contains strictly internal classes for this Chronicle library. 3 | * Internal classes shall never be used directly. 4 | * 5 | * Specifically, the following actions (including, but not limited to) are not allowed 6 | * on internal classes and packages: 7 | * 8 | * Casting to 9 | * Reflection of any kind 10 | * Explicit Serialize/deserialize 11 | * 12 | * 13 | * The classes in this package and any sub-package are subject to 14 | * changes at any time for any reason. 15 | */ 16 | package net.openhft.chronicle.logger.slf4j2.internal; 17 | -------------------------------------------------------------------------------- /logger-slf4j-2/src/main/java/org/slf4j/impl/ChronicleServiceProvider.java: -------------------------------------------------------------------------------- 1 | package org.slf4j.impl; 2 | 3 | import net.openhft.chronicle.logger.slf4j2.ChronicleLoggerFactory; 4 | import org.slf4j.ILoggerFactory; 5 | import org.slf4j.IMarkerFactory; 6 | import org.slf4j.helpers.BasicMarkerFactory; 7 | import org.slf4j.helpers.NOPMDCAdapter; 8 | import org.slf4j.spi.MDCAdapter; 9 | import org.slf4j.spi.SLF4JServiceProvider; 10 | 11 | public class ChronicleServiceProvider implements SLF4JServiceProvider { 12 | 13 | /** 14 | * Declare the version of the SLF4J API this implementation is compiled against. 15 | * The value of this field is modified with each major release. 16 | */ 17 | // to avoid constant folding by the compiler, this field must *not* be final 18 | public static String REQUESTED_API_VERSION = "2.0.99"; // !final 19 | 20 | public ChronicleServiceProvider() {} 21 | /** 22 | * The ILoggerFactory instance returned by the {@link #getLoggerFactory} 23 | * method should always be the same object 24 | */ 25 | private ILoggerFactory loggerFactory; 26 | 27 | private IMarkerFactory markerFactory; 28 | private MDCAdapter mdcAdapter; 29 | 30 | @Override 31 | public ILoggerFactory getLoggerFactory() { 32 | return loggerFactory; 33 | } 34 | 35 | @Override 36 | public IMarkerFactory getMarkerFactory() { 37 | return markerFactory; 38 | } 39 | 40 | @Override 41 | public MDCAdapter getMDCAdapter() { 42 | return mdcAdapter; 43 | } 44 | 45 | @Override 46 | public String getRequestedApiVersion() { 47 | return REQUESTED_API_VERSION; 48 | } 49 | 50 | @Override 51 | public void initialize() { 52 | loggerFactory = new ChronicleLoggerFactory(); 53 | markerFactory = new BasicMarkerFactory(); 54 | mdcAdapter = new NOPMDCAdapter(); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /logger-slf4j-2/src/main/java/org/slf4j/impl/OutputChoice.java: -------------------------------------------------------------------------------- 1 | package org.slf4j.impl; 2 | 3 | import java.io.PrintStream; 4 | 5 | /** 6 | * This class encapsulates the user's choice of output target. 7 | * 8 | * @author Ceki Gülcü 9 | * 10 | */ 11 | class OutputChoice { 12 | 13 | enum OutputChoiceType { 14 | SYS_OUT, CACHED_SYS_OUT, SYS_ERR, CACHED_SYS_ERR, FILE; 15 | } 16 | 17 | final OutputChoiceType outputChoiceType; 18 | final PrintStream targetPrintStream; 19 | 20 | OutputChoice(OutputChoiceType outputChoiceType) { 21 | if (outputChoiceType == OutputChoiceType.FILE) { 22 | throw new IllegalArgumentException(); 23 | } 24 | this.outputChoiceType = outputChoiceType; 25 | if (outputChoiceType == OutputChoiceType.CACHED_SYS_OUT) { 26 | this.targetPrintStream = System.out; 27 | } else if (outputChoiceType == OutputChoiceType.CACHED_SYS_ERR) { 28 | this.targetPrintStream = System.err; 29 | } else { 30 | this.targetPrintStream = null; 31 | } 32 | } 33 | 34 | OutputChoice(PrintStream printStream) { 35 | this.outputChoiceType = OutputChoiceType.FILE; 36 | this.targetPrintStream = printStream; 37 | } 38 | 39 | PrintStream getTargetPrintStream() { 40 | switch (outputChoiceType) { 41 | case SYS_OUT: 42 | return System.out; 43 | case SYS_ERR: 44 | return System.err; 45 | case CACHED_SYS_ERR: 46 | case CACHED_SYS_OUT: 47 | case FILE: 48 | return targetPrintStream; 49 | default: 50 | throw new IllegalArgumentException(); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /logger-slf4j-2/src/main/resources/META-INF/services/org.slf4j.spi.SLF4JServiceProvider: -------------------------------------------------------------------------------- 1 | org.slf4j.impl.ChronicleServiceProvider 2 | -------------------------------------------------------------------------------- /logger-slf4j-2/src/test/java/net/openhft/chronicle/logger/slf4j2/ChronicleLoggingConfigTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.slf4j2; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogConfig; 21 | import org.junit.Test; 22 | 23 | import static org.junit.Assert.assertNotNull; 24 | 25 | public class ChronicleLoggingConfigTest { 26 | @Test 27 | public void testLoadClasspathIndexed() { 28 | System.setProperty("chronicle.logger.properties", "chronicle.logger.properties"); 29 | assertLoadsValidConfig(); 30 | } 31 | 32 | private void assertLoadsValidConfig() { 33 | ChronicleLogConfig config = ChronicleLogConfig.load(); 34 | assertNotNull("unable to load config", config); 35 | assertNotNull("is not a valid config", config.getAppenderConfig()); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /logger-slf4j-2/src/test/java/net/openhft/chronicle/logger/slf4j2/Slf4jChronicleConfigurationTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.slf4j2; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogConfig; 21 | import net.openhft.chronicle.logger.ChronicleLogLevel; 22 | import org.junit.Test; 23 | 24 | import java.io.File; 25 | import java.util.Properties; 26 | 27 | import static org.junit.Assert.assertEquals; 28 | import static org.junit.Assert.assertNotNull; 29 | 30 | public class Slf4jChronicleConfigurationTest extends Slf4jTestBase { 31 | 32 | @Test 33 | public void testLoadProperties() { 34 | final String cfgPath = "chronicle.logger.properties"; 35 | final ChronicleLogConfig cfg = ChronicleLogConfig.load(cfgPath); 36 | 37 | assertNotNull(cfg); 38 | 39 | assertEquals( 40 | new File(basePath("root")), 41 | new File(cfg.getString(ChronicleLogConfig.KEY_PATH))); 42 | assertEquals( 43 | ChronicleLogLevel.DEBUG.toString(), 44 | cfg.getString(ChronicleLogConfig.KEY_LEVEL).toUpperCase()); 45 | assertEquals("false", cfg.getString(ChronicleLogConfig.KEY_APPEND)); 46 | assertEquals( 47 | new File(basePath("logger_1")), 48 | new File(cfg.getString("logger_1", ChronicleLogConfig.KEY_PATH))); 49 | assertEquals( 50 | ChronicleLogLevel.INFO.toString(), 51 | cfg.getString("logger_1", ChronicleLogConfig.KEY_LEVEL).toUpperCase()); 52 | assertEquals( 53 | ChronicleLogLevel.DEBUG.toString(), 54 | cfg.getString("readwrite", ChronicleLogConfig.KEY_LEVEL).toUpperCase()); 55 | } 56 | 57 | @Test 58 | public void testLoadConfig() { 59 | final Properties properties = new Properties(); 60 | properties.setProperty("chronicle.logger.root.cfg.blockSize", "256"); 61 | 62 | final ChronicleLogConfig clc = ChronicleLogConfig.load(properties); 63 | assertNotNull(clc.getAppenderConfig()); 64 | 65 | assertEquals(256, clc.getAppenderConfig().getBlockSize()); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /logger-slf4j-2/src/test/java/net/openhft/chronicle/logger/slf4j2/Slf4jChronicleLoggerPerfTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.slf4j2; 19 | 20 | import net.openhft.chronicle.core.io.IOTools; 21 | import org.apache.commons.lang3.StringUtils; 22 | import org.junit.After; 23 | import org.junit.Before; 24 | import org.junit.Ignore; 25 | import org.junit.Test; 26 | import org.slf4j.Logger; 27 | import org.slf4j.LoggerFactory; 28 | 29 | import java.util.concurrent.ExecutorService; 30 | import java.util.concurrent.Executors; 31 | import java.util.concurrent.TimeUnit; 32 | 33 | @Ignore 34 | public class Slf4jChronicleLoggerPerfTest extends Slf4jTestBase { 35 | 36 | // ************************************************************************* 37 | // 38 | // ************************************************************************* 39 | 40 | @Before 41 | public void setUp() { 42 | System.setProperty( 43 | "chronicle.logger.properties", 44 | "chronicle.logger.perf.properties"); 45 | 46 | getChronicleLoggerFactory().reload(); 47 | } 48 | 49 | @After 50 | public void tearDown() { 51 | IOTools.deleteDirWithFiles(basePath()); 52 | } 53 | 54 | // ************************************************************************* 55 | // Single Thread 56 | // ************************************************************************* 57 | 58 | @Test 59 | public void testSingleThreadLogging1() { 60 | Thread.currentThread().setName("perf-plain"); 61 | 62 | final String testId = "perf-chronicle"; 63 | final Logger clogger = LoggerFactory.getLogger(testId); 64 | final long items = 1000000; 65 | 66 | warmup(clogger); 67 | 68 | for (int s = 64; s <= 1024; s += 64) { 69 | final String staticStr = StringUtils.leftPad("", s, 'X'); 70 | 71 | long cStart1 = System.nanoTime(); 72 | 73 | for (int i = 1; i <= items; i++) { 74 | clogger.info(staticStr); 75 | } 76 | 77 | long cEnd1 = System.nanoTime(); 78 | 79 | System.out.printf("items=%03d size=%04d => chronology=%.3f ms, chronology-average=%.3f us\n", 80 | items, 81 | staticStr.length(), 82 | (cEnd1 - cStart1) / 1e6, 83 | (cEnd1 - cStart1) / items / 1e3); 84 | } 85 | } 86 | 87 | @Test 88 | public void testSingleThreadLogging2() { 89 | Thread.currentThread().setName("perf-plain"); 90 | 91 | final String testId = "perf-chronicle"; 92 | final Logger clogger = LoggerFactory.getLogger(testId); 93 | final long items = 1000000; 94 | final String strFmt = StringUtils.leftPad("> v1={}, v2={}, v3={}", 32, 'X'); 95 | 96 | warmup(clogger); 97 | 98 | for (int n = 0; n < 10; n++) { 99 | long cStart1 = System.nanoTime(); 100 | 101 | for (int i = 1; i <= items; i++) { 102 | clogger.info(strFmt, i, i * 10, i / 16); 103 | } 104 | 105 | long cEnd1 = System.nanoTime(); 106 | 107 | System.out.printf("items=%03d => chronology=%.3f ms, chronology-average=%.3f us\n", 108 | items, 109 | (cEnd1 - cStart1) / 1e6, 110 | (cEnd1 - cStart1) / items / 1e3); 111 | } 112 | } 113 | 114 | // ************************************************************************* 115 | // Multi Thread 116 | // ************************************************************************* 117 | 118 | @Test 119 | public void testMultiThreadLogging() throws InterruptedException { 120 | warmup(LoggerFactory.getLogger("perf-chronicle")); 121 | 122 | final int RUNS = 1000000; 123 | final int THREADS = 10; 124 | 125 | for (int size : new int[]{64, 128, 256}) { 126 | { 127 | final long start = System.nanoTime(); 128 | 129 | ExecutorService es = Executors.newFixedThreadPool(THREADS); 130 | for (int t = 0; t < THREADS; t++) { 131 | es.submit(new RunnableLogger(RUNS, size, "perf-chronicle")); 132 | } 133 | 134 | es.shutdown(); 135 | es.awaitTermination(5, TimeUnit.SECONDS); 136 | 137 | final long time = System.nanoTime() - start; 138 | 139 | System.out.printf("ChronicleLog.MT (runs=%d, min size=%03d, elapsed=%.3f ms) took an average of %.3f us per entry\n", 140 | RUNS, 141 | size, 142 | time / 1e6, 143 | time / 1e3 / (RUNS * THREADS) 144 | ); 145 | } 146 | } 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /logger-slf4j-2/src/test/java/net/openhft/chronicle/logger/slf4j2/Slf4jTestBase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.slf4j2; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogLevel; 21 | import net.openhft.chronicle.logger.slf4j2.ChronicleLoggerFactory; 22 | import org.apache.commons.lang3.StringUtils; 23 | import org.slf4j.Logger; 24 | import org.slf4j.LoggerFactory; 25 | import org.slf4j.impl.ChronicleServiceProvider; 26 | 27 | class Slf4jTestBase { 28 | 29 | // ************************************************************************* 30 | // 31 | // ************************************************************************* 32 | 33 | static final ChronicleLogLevel[] LOG_LEVELS = ChronicleLogLevel.values(); 34 | 35 | static String basePath() { 36 | String path = System.getProperty("java.io.tmpdir"); 37 | String sep = System.getProperty("file.separator"); 38 | 39 | if (!path.endsWith(sep)) { 40 | path += sep; 41 | } 42 | 43 | return path + "chronicle-slf4j"; 44 | } 45 | 46 | static String basePath(String loggerName) { 47 | return basePath() 48 | + System.getProperty("file.separator") 49 | + loggerName; 50 | } 51 | 52 | static void log(Logger logger, ChronicleLogLevel level, String fmt, Object... args) { 53 | switch (level) { 54 | case TRACE: 55 | logger.trace(fmt, args); 56 | break; 57 | 58 | case DEBUG: 59 | logger.debug(fmt, args); 60 | break; 61 | 62 | case INFO: 63 | logger.info(fmt, args); 64 | break; 65 | 66 | case WARN: 67 | logger.warn(fmt, args); 68 | break; 69 | 70 | case ERROR: 71 | logger.error(fmt, args); 72 | break; 73 | default: 74 | throw new UnsupportedOperationException(); 75 | } 76 | } 77 | 78 | static void warmup(Logger logger) { 79 | for (int i = 0; i < 10; i++) { 80 | logger.info("warmup"); 81 | } 82 | } 83 | 84 | // ************************************************************************* 85 | // 86 | // ************************************************************************* 87 | 88 | /** 89 | * @return the ChronicleLoggerFactory singleton 90 | */ 91 | ChronicleLoggerFactory getChronicleLoggerFactory() { 92 | ChronicleServiceProvider provider = new ChronicleServiceProvider(); 93 | provider.initialize(); 94 | return (ChronicleLoggerFactory) provider.getLoggerFactory(); 95 | } 96 | 97 | // ************************************************************************* 98 | // 99 | // ************************************************************************* 100 | 101 | protected final class RunnableLogger implements Runnable { 102 | private final Logger logger; 103 | private final int runs; 104 | private final String fmt; 105 | private final String fmtBase = " > val1={}, val2={}, val3={}"; 106 | 107 | public RunnableLogger(int runs, int pad, String loggerName) { 108 | this.logger = LoggerFactory.getLogger(loggerName); 109 | this.runs = runs; 110 | this.fmt = StringUtils.rightPad(fmtBase, pad + fmtBase.length() - (4 + 8 + 8), "X"); 111 | } 112 | 113 | @Override 114 | public void run() { 115 | for (int i = 0; i < this.runs; i++) { 116 | this.logger.info(fmt, i, i * 7L, i / 16.0); 117 | } 118 | } 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /logger-slf4j-2/src/test/resources/chronicle.logger.perf.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2014-2017 Chronicle Software 3 | # 4 | # https://chronicle.software 5 | # 6 | # This program is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License 16 | # along with this program. If not, see . 17 | # 18 | 19 | chronicle.logger.base = ${java.io.tmpdir}/chronicle-slf4j 20 | 21 | chronicle.logger.root.path = ${chronicle.logger.base}/perf 22 | chronicle.logger.root.level = debug 23 | chronicle.logger.root.append = false 24 | -------------------------------------------------------------------------------- /logger-slf4j-2/src/test/resources/chronicle.logger.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2014-2017 Chronicle Software 3 | # 4 | # https://chronicle.software 5 | # 6 | # This program is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License 16 | # along with this program. If not, see . 17 | # 18 | 19 | ################################################################################ 20 | # Common 21 | ################################################################################ 22 | 23 | chronicle.logger.base = ${java.io.tmpdir}/chronicle-slf4j 24 | chronicle.logger.root.path = ${chronicle.logger.base}/root 25 | chronicle.logger.root.level = debug 26 | chronicle.logger.root.append = false 27 | 28 | ################################################################################ 29 | # Loggers 30 | ################################################################################ 31 | 32 | # logger : Logger1 33 | chronicle.logger.logger_1.path = ${chronicle.logger.base}/logger_1 34 | chronicle.logger.logger_1.level = info 35 | 36 | # logger : impl 37 | chronicle.logger.readwrite.path = ${chronicle.logger.base}/readwrite 38 | -------------------------------------------------------------------------------- /logger-slf4j/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 22 | 23 | 4.0.0 24 | 25 | 26 | net.openhft 27 | chronicle-logger 28 | 4.27ea2-SNAPSHOT 29 | ../pom.xml 30 | 31 | 32 | OpenHFT/Chronicle-Logger/logger-slf4j 33 | chronicle-logger-slf4j 34 | bundle 35 | 36 | 37 | 38 | net.openhft 39 | chronicle-logger-core 40 | 41 | 42 | 43 | 44 | org.slf4j 45 | slf4j-api 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | org.apache.maven.plugins 54 | maven-surefire-plugin 55 | 56 | 57 | **/*PerfTest.java 58 | 59 | 60 | ${project.build.directory} 61 | 62 | 63 | 64 | 72 | 73 | org.apache.servicemix.tooling 74 | depends-maven-plugin 75 | 76 | 77 | generate-depends-file 78 | 79 | generate-depends-file 80 | 81 | 82 | 83 | 84 | 85 | org.apache.felix 86 | maven-bundle-plugin 87 | true 88 | 89 | 90 | ${project.groupId}.${project.artifactId} 91 | OpenHFT :: ${project.artifactId} 92 | ${project.version} 93 | net.openhft.chronicle.logger.slf4j.* 94 | 95 | 96 | 97 | 101 | 102 | 103 | manifest 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 113 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 114 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 115 | master 116 | 117 | 118 | 119 | -------------------------------------------------------------------------------- /logger-slf4j/src/main/java/net/openhft/chronicle/logger/slf4j/ChronicleLoggerFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.slf4j; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogManager; 21 | import net.openhft.chronicle.logger.ChronicleLogWriter; 22 | import org.slf4j.ILoggerFactory; 23 | import org.slf4j.Logger; 24 | import org.slf4j.helpers.NOPLogger; 25 | import org.slf4j.impl.SimpleLogger; 26 | 27 | import java.util.Map; 28 | import java.util.concurrent.ConcurrentHashMap; 29 | 30 | /** 31 | * Simple implementation of Logger that sends all enabled slf4j messages, 32 | * for all defined loggers, to one or more VanillaChronicle.. 33 | * 34 | * To configure this sl4j binding you need to specify the location of a properties 35 | * files via system properties: 36 | * {@code -Dchronicle.logger.properties=${pathOfYourPropertiesFile}} 37 | * 38 | * The following system properties are supported to configure the behavior of this 39 | * logger: 40 | * 41 | * {@code chronicle.logger.root.path} 42 | * {@code chronicle.logger.root.level} 43 | * {@code chronicle.logger.root.append} 44 | * 45 | */ 46 | public class ChronicleLoggerFactory implements ILoggerFactory { 47 | private final Map loggers; 48 | private final ChronicleLogManager manager; 49 | 50 | // ************************************************************************* 51 | // 52 | // ************************************************************************* 53 | 54 | /** 55 | * c-tor 56 | */ 57 | public ChronicleLoggerFactory() { 58 | this.loggers = new ConcurrentHashMap<>(); 59 | this.manager = ChronicleLogManager.getInstance(); 60 | } 61 | 62 | // ************************************************************************* 63 | // for testing 64 | // ************************************************************************* 65 | 66 | /** 67 | * Return an appropriate {@link ChronicleLogger} instance by name. 68 | */ 69 | @Override 70 | public Logger getLogger(String name) { 71 | try { 72 | return doGetLogger(name); 73 | } catch (Exception e) { 74 | System.err.println("Unable to initialize chronicle-logger-slf4j (" + name + ")\n " + e.getMessage()); 75 | e.printStackTrace(); 76 | } 77 | 78 | return NOPLogger.NOP_LOGGER; 79 | } 80 | 81 | // ************************************************************************* 82 | // 83 | // ************************************************************************* 84 | 85 | synchronized void reload() { 86 | this.loggers.clear(); 87 | this.manager.reload(); 88 | } 89 | 90 | private synchronized Logger doGetLogger(String name) { 91 | Logger logger = loggers.get(name); 92 | if (logger == null) { 93 | if (name != null && name.startsWith("net.openhft")) { 94 | SimpleLogger.lazyInit(); 95 | logger = new SimpleLogger(name); 96 | } else { 97 | final ChronicleLogWriter writer = manager.getWriter(name); 98 | logger = new ChronicleLogger(writer, name, manager.cfg().getLevel(name)); 99 | } 100 | loggers.put(name, logger); 101 | } 102 | 103 | return logger; 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /logger-slf4j/src/main/java/net/openhft/chronicle/logger/slf4j/internal/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This package and any and all sub-packages contains strictly internal classes for this Chronicle library. 3 | * Internal classes shall never be used directly. 4 | * 5 | * Specifically, the following actions (including, but not limited to) are not allowed 6 | * on internal classes and packages: 7 | * 8 | * Casting to 9 | * Reflection of any kind 10 | * Explicit Serialize/deserialize 11 | * 12 | * 13 | * The classes in this package and any sub-package are subject to 14 | * changes at any time for any reason. 15 | */ 16 | package net.openhft.chronicle.logger.slf4j.internal; 17 | -------------------------------------------------------------------------------- /logger-slf4j/src/main/java/org/slf4j/impl/OutputChoice.java: -------------------------------------------------------------------------------- 1 | package org.slf4j.impl; 2 | 3 | import java.io.PrintStream; 4 | 5 | /** 6 | * This class encapsulates the user's choice of output target. 7 | * 8 | * @author Ceki Gülcü 9 | * 10 | */ 11 | class OutputChoice { 12 | 13 | enum OutputChoiceType { 14 | SYS_OUT, CACHED_SYS_OUT, SYS_ERR, CACHED_SYS_ERR, FILE; 15 | } 16 | 17 | final OutputChoiceType outputChoiceType; 18 | final PrintStream targetPrintStream; 19 | 20 | OutputChoice(OutputChoiceType outputChoiceType) { 21 | if (outputChoiceType == OutputChoiceType.FILE) { 22 | throw new IllegalArgumentException(); 23 | } 24 | this.outputChoiceType = outputChoiceType; 25 | if (outputChoiceType == OutputChoiceType.CACHED_SYS_OUT) { 26 | this.targetPrintStream = System.out; 27 | } else if (outputChoiceType == OutputChoiceType.CACHED_SYS_ERR) { 28 | this.targetPrintStream = System.err; 29 | } else { 30 | this.targetPrintStream = null; 31 | } 32 | } 33 | 34 | OutputChoice(PrintStream printStream) { 35 | this.outputChoiceType = OutputChoiceType.FILE; 36 | this.targetPrintStream = printStream; 37 | } 38 | 39 | PrintStream getTargetPrintStream() { 40 | switch (outputChoiceType) { 41 | case SYS_OUT: 42 | return System.out; 43 | case SYS_ERR: 44 | return System.err; 45 | case CACHED_SYS_ERR: 46 | case CACHED_SYS_OUT: 47 | case FILE: 48 | return targetPrintStream; 49 | default: 50 | throw new IllegalArgumentException(); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /logger-slf4j/src/main/java/org/slf4j/impl/StaticLoggerBinder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.slf4j.impl; 19 | 20 | import net.openhft.chronicle.logger.slf4j.ChronicleLoggerFactory; 21 | import org.slf4j.ILoggerFactory; 22 | import org.slf4j.spi.LoggerFactoryBinder; 23 | 24 | public class StaticLoggerBinder implements LoggerFactoryBinder { 25 | 26 | private static final StaticLoggerBinder SINGLETON = new StaticLoggerBinder(); 27 | private static final String loggerFactoryClassStr = ChronicleLoggerFactory.class.getName(); 28 | /** 29 | * Declare the version of the SLF4J API this implementation is compiled 30 | * against. The value of this field is usually modified with each release. 31 | */ 32 | // to avoid constant folding by the compiler, this field must *not* be final 33 | public static String REQUESTED_API_VERSION = "1.7.30"; // !final 34 | /** 35 | * The ILoggerFactory instance returned by the {@link #getLoggerFactory} 36 | * method should always be the same object 37 | */ 38 | private final ILoggerFactory loggerFactory; 39 | 40 | /** 41 | * c-tor 42 | */ 43 | private StaticLoggerBinder() { 44 | loggerFactory = new ChronicleLoggerFactory(); 45 | } 46 | 47 | /** 48 | * Return the singleton of this class. 49 | * 50 | * @return the StaticLoggerBinder singleton 51 | */ 52 | public static final StaticLoggerBinder getSingleton() { 53 | return SINGLETON; 54 | } 55 | 56 | @Override 57 | public ILoggerFactory getLoggerFactory() { 58 | return loggerFactory; 59 | } 60 | 61 | @Override 62 | public String getLoggerFactoryClassStr() { 63 | return loggerFactoryClassStr; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /logger-slf4j/src/main/java/org/slf4j/impl/StaticMarkerBinder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.slf4j.impl; 19 | 20 | import org.slf4j.IMarkerFactory; 21 | import org.slf4j.helpers.BasicMarkerFactory; 22 | import org.slf4j.spi.MarkerFactoryBinder; 23 | 24 | /** 25 | * The binding of {@link org.slf4j.MarkerFactory} class with an actual instance of 26 | * {@link IMarkerFactory} is performed using information returned by this class. 27 | * 28 | * @author Ceki Gülcü 29 | */ 30 | public class StaticMarkerBinder implements MarkerFactoryBinder { 31 | 32 | /** 33 | * The unique instance of this class. 34 | */ 35 | public static final StaticMarkerBinder SINGLETON = new StaticMarkerBinder(); 36 | 37 | final IMarkerFactory markerFactory = new BasicMarkerFactory(); 38 | 39 | private StaticMarkerBinder() { 40 | } 41 | 42 | /** 43 | * Currently this method always returns an instance of 44 | * {@link BasicMarkerFactory}. 45 | */ 46 | @Override 47 | public IMarkerFactory getMarkerFactory() { 48 | return markerFactory; 49 | } 50 | 51 | /** 52 | * Currently, this method returns the class name of 53 | * {@link BasicMarkerFactory}. 54 | */ 55 | @Override 56 | public String getMarkerFactoryClassStr() { 57 | return BasicMarkerFactory.class.getName(); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /logger-slf4j/src/test/java/net/openhft/chronicle/logger/slf4j/ChronicleLoggingConfigTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.slf4j; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogConfig; 21 | import org.junit.Test; 22 | 23 | import static org.junit.Assert.assertNotNull; 24 | 25 | public class ChronicleLoggingConfigTest { 26 | @Test 27 | public void testLoadClasspathIndexed() { 28 | System.setProperty("chronicle.logger.properties", "chronicle.logger.properties"); 29 | assertLoadsValidConfig(); 30 | } 31 | 32 | private void assertLoadsValidConfig() { 33 | ChronicleLogConfig config = ChronicleLogConfig.load(); 34 | assertNotNull("unable to load config", config); 35 | assertNotNull("is not a valid config", config.getAppenderConfig()); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /logger-slf4j/src/test/java/net/openhft/chronicle/logger/slf4j/Slf4jChronicleConfigurationTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.slf4j; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogConfig; 21 | import net.openhft.chronicle.logger.ChronicleLogLevel; 22 | import org.junit.Test; 23 | 24 | import java.io.File; 25 | import java.util.Properties; 26 | 27 | import static org.junit.Assert.assertEquals; 28 | import static org.junit.Assert.assertNotNull; 29 | 30 | public class Slf4jChronicleConfigurationTest extends Slf4jTestBase { 31 | 32 | @Test 33 | public void testLoadProperties() { 34 | final String cfgPath = "chronicle.logger.properties"; 35 | final ChronicleLogConfig cfg = ChronicleLogConfig.load(cfgPath); 36 | 37 | assertNotNull(cfg); 38 | 39 | assertEquals( 40 | new File(basePath("root")), 41 | new File(cfg.getString(ChronicleLogConfig.KEY_PATH))); 42 | assertEquals( 43 | ChronicleLogLevel.DEBUG.toString(), 44 | cfg.getString(ChronicleLogConfig.KEY_LEVEL).toUpperCase()); 45 | assertEquals("false", cfg.getString(ChronicleLogConfig.KEY_APPEND)); 46 | assertEquals( 47 | new File(basePath("logger_1")), 48 | new File(cfg.getString("logger_1", ChronicleLogConfig.KEY_PATH))); 49 | assertEquals( 50 | ChronicleLogLevel.INFO.toString(), 51 | cfg.getString("logger_1", ChronicleLogConfig.KEY_LEVEL).toUpperCase()); 52 | assertEquals( 53 | ChronicleLogLevel.DEBUG.toString(), 54 | cfg.getString("readwrite", ChronicleLogConfig.KEY_LEVEL).toUpperCase()); 55 | } 56 | 57 | @Test 58 | public void testLoadConfig() { 59 | final Properties properties = new Properties(); 60 | properties.setProperty("chronicle.logger.root.cfg.blockSize", "256"); 61 | 62 | final ChronicleLogConfig clc = ChronicleLogConfig.load(properties); 63 | assertNotNull(clc.getAppenderConfig()); 64 | 65 | assertEquals(256, clc.getAppenderConfig().getBlockSize()); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /logger-slf4j/src/test/java/net/openhft/chronicle/logger/slf4j/Slf4jChronicleLoggerPerfTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.slf4j; 19 | 20 | import net.openhft.chronicle.core.io.IOTools; 21 | import org.apache.commons.lang3.StringUtils; 22 | import org.junit.After; 23 | import org.junit.Before; 24 | import org.junit.Ignore; 25 | import org.junit.Test; 26 | import org.slf4j.Logger; 27 | import org.slf4j.LoggerFactory; 28 | 29 | import java.util.concurrent.ExecutorService; 30 | import java.util.concurrent.Executors; 31 | import java.util.concurrent.TimeUnit; 32 | 33 | @Ignore 34 | public class Slf4jChronicleLoggerPerfTest extends Slf4jTestBase { 35 | 36 | // ************************************************************************* 37 | // 38 | // ************************************************************************* 39 | 40 | @Before 41 | public void setUp() { 42 | System.setProperty( 43 | "chronicle.logger.properties", 44 | "chronicle.logger.perf.properties"); 45 | 46 | getChronicleLoggerFactory().reload(); 47 | } 48 | 49 | @After 50 | public void tearDown() { 51 | IOTools.deleteDirWithFiles(basePath()); 52 | } 53 | 54 | // ************************************************************************* 55 | // Single Thread 56 | // ************************************************************************* 57 | 58 | @Test 59 | public void testSingleThreadLogging1() { 60 | Thread.currentThread().setName("perf-plain"); 61 | 62 | final String testId = "perf-chronicle"; 63 | final Logger clogger = LoggerFactory.getLogger(testId); 64 | final long items = 1000000; 65 | 66 | warmup(clogger); 67 | 68 | for (int s = 64; s <= 1024; s += 64) { 69 | final String staticStr = StringUtils.leftPad("", s, 'X'); 70 | 71 | long cStart1 = System.nanoTime(); 72 | 73 | for (int i = 1; i <= items; i++) { 74 | clogger.info(staticStr); 75 | } 76 | 77 | long cEnd1 = System.nanoTime(); 78 | 79 | System.out.printf("items=%03d size=%04d => chronology=%.3f ms, chronology-average=%.3f us\n", 80 | items, 81 | staticStr.length(), 82 | (cEnd1 - cStart1) / 1e6, 83 | (cEnd1 - cStart1) / items / 1e3); 84 | } 85 | } 86 | 87 | @Test 88 | public void testSingleThreadLogging2() { 89 | Thread.currentThread().setName("perf-plain"); 90 | 91 | final String testId = "perf-chronicle"; 92 | final Logger clogger = LoggerFactory.getLogger(testId); 93 | final long items = 1000000; 94 | final String strFmt = StringUtils.leftPad("> v1={}, v2={}, v3={}", 32, 'X'); 95 | 96 | warmup(clogger); 97 | 98 | for (int n = 0; n < 10; n++) { 99 | long cStart1 = System.nanoTime(); 100 | 101 | for (int i = 1; i <= items; i++) { 102 | clogger.info(strFmt, i, i * 10, i / 16); 103 | } 104 | 105 | long cEnd1 = System.nanoTime(); 106 | 107 | System.out.printf("items=%03d => chronology=%.3f ms, chronology-average=%.3f us\n", 108 | items, 109 | (cEnd1 - cStart1) / 1e6, 110 | (cEnd1 - cStart1) / items / 1e3); 111 | } 112 | } 113 | 114 | // ************************************************************************* 115 | // Multi Thread 116 | // ************************************************************************* 117 | 118 | @Test 119 | public void testMultiThreadLogging() throws InterruptedException { 120 | warmup(LoggerFactory.getLogger("perf-chronicle")); 121 | 122 | final int RUNS = 1000000; 123 | final int THREADS = 10; 124 | 125 | for (int size : new int[]{64, 128, 256}) { 126 | { 127 | final long start = System.nanoTime(); 128 | 129 | ExecutorService es = Executors.newFixedThreadPool(THREADS); 130 | for (int t = 0; t < THREADS; t++) { 131 | es.submit(new RunnableLogger(RUNS, size, "perf-chronicle")); 132 | } 133 | 134 | es.shutdown(); 135 | es.awaitTermination(5, TimeUnit.SECONDS); 136 | 137 | final long time = System.nanoTime() - start; 138 | 139 | System.out.printf("ChronicleLog.MT (runs=%d, min size=%03d, elapsed=%.3f ms) took an average of %.3f us per entry\n", 140 | RUNS, 141 | size, 142 | time / 1e6, 143 | time / 1e3 / (RUNS * THREADS) 144 | ); 145 | } 146 | } 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /logger-slf4j/src/test/java/net/openhft/chronicle/logger/slf4j/Slf4jTestBase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.slf4j; 19 | 20 | import net.openhft.chronicle.core.OS; 21 | import net.openhft.chronicle.core.util.Time; 22 | import net.openhft.chronicle.logger.ChronicleLogLevel; 23 | import org.apache.commons.lang3.StringUtils; 24 | import org.slf4j.Logger; 25 | import org.slf4j.LoggerFactory; 26 | import org.slf4j.impl.StaticLoggerBinder; 27 | 28 | class Slf4jTestBase { 29 | 30 | // ************************************************************************* 31 | // 32 | // ************************************************************************* 33 | 34 | static final ChronicleLogLevel[] LOG_LEVELS = ChronicleLogLevel.values(); 35 | 36 | static String basePath() { 37 | String path = System.getProperty("java.io.tmpdir"); 38 | String sep = System.getProperty("file.separator"); 39 | 40 | if (!path.endsWith(sep)) { 41 | path += sep; 42 | } 43 | 44 | return path + "chronicle-slf4j"; 45 | } 46 | 47 | static String basePath(String loggerName) { 48 | return basePath() 49 | + System.getProperty("file.separator") 50 | + loggerName; 51 | } 52 | 53 | static void log(Logger logger, ChronicleLogLevel level, String fmt, Object... args) { 54 | switch (level) { 55 | case TRACE: 56 | logger.trace(fmt, args); 57 | break; 58 | 59 | case DEBUG: 60 | logger.debug(fmt, args); 61 | break; 62 | 63 | case INFO: 64 | logger.info(fmt, args); 65 | break; 66 | 67 | case WARN: 68 | logger.warn(fmt, args); 69 | break; 70 | 71 | case ERROR: 72 | logger.error(fmt, args); 73 | break; 74 | default: 75 | throw new UnsupportedOperationException(); 76 | } 77 | } 78 | 79 | static void warmup(Logger logger) { 80 | for (int i = 0; i < 10; i++) { 81 | logger.info("warmup"); 82 | } 83 | } 84 | 85 | // ************************************************************************* 86 | // 87 | // ************************************************************************* 88 | 89 | /** 90 | * @return the ChronicleLoggerFactory singleton 91 | */ 92 | ChronicleLoggerFactory getChronicleLoggerFactory() { 93 | return (ChronicleLoggerFactory) StaticLoggerBinder.getSingleton().getLoggerFactory(); 94 | } 95 | 96 | // ************************************************************************* 97 | // 98 | // ************************************************************************* 99 | 100 | protected final class RunnableLogger implements Runnable { 101 | private final Logger logger; 102 | private final int runs; 103 | private final String fmt; 104 | private final String fmtBase = " > val1={}, val2={}, val3={}"; 105 | 106 | public RunnableLogger(int runs, int pad, String loggerName) { 107 | this.logger = LoggerFactory.getLogger(loggerName); 108 | this.runs = runs; 109 | this.fmt = StringUtils.rightPad(fmtBase, pad + fmtBase.length() - (4 + 8 + 8), "X"); 110 | } 111 | 112 | @Override 113 | public void run() { 114 | for (int i = 0; i < this.runs; i++) { 115 | this.logger.info(fmt, i, i * 7L, i / 16.0); 116 | } 117 | } 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /logger-slf4j/src/test/resources/chronicle.logger.perf.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2014-2017 Chronicle Software 3 | # 4 | # https://chronicle.software 5 | # 6 | # This program is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License 16 | # along with this program. If not, see . 17 | # 18 | 19 | chronicle.logger.base = ${java.io.tmpdir}/chronicle-slf4j 20 | 21 | chronicle.logger.root.path = ${chronicle.logger.base}/perf 22 | chronicle.logger.root.level = debug 23 | chronicle.logger.root.append = false 24 | -------------------------------------------------------------------------------- /logger-slf4j/src/test/resources/chronicle.logger.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2014-2017 Chronicle Software 3 | # 4 | # https://chronicle.software 5 | # 6 | # This program is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License 16 | # along with this program. If not, see . 17 | # 18 | 19 | ################################################################################ 20 | # Common 21 | ################################################################################ 22 | 23 | chronicle.logger.base = ${java.io.tmpdir}/chronicle-slf4j 24 | chronicle.logger.root.path = ${chronicle.logger.base}/root 25 | chronicle.logger.root.level = debug 26 | chronicle.logger.root.append = false 27 | 28 | ################################################################################ 29 | # Loggers 30 | ################################################################################ 31 | 32 | # logger : Logger1 33 | chronicle.logger.logger_1.path = ${chronicle.logger.base}/logger_1 34 | chronicle.logger.logger_1.level = info 35 | 36 | # logger : impl 37 | chronicle.logger.readwrite.path = ${chronicle.logger.base}/readwrite 38 | -------------------------------------------------------------------------------- /logger-tools/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 22 | 23 | 4.0.0 24 | 25 | 26 | net.openhft 27 | chronicle-logger 28 | 4.27ea2-SNAPSHOT 29 | ../pom.xml 30 | 31 | 32 | OpenHFT/Chronicle-Logger/logger-tools 33 | chronicle-logger-tools 34 | bundle 35 | 36 | 37 | 38 | net.openhft 39 | chronicle-logger-core 40 | 41 | 42 | 43 | net.openhft 44 | chronicle-wire 45 | 46 | 47 | 48 | 49 | org.slf4j 50 | slf4j-api 51 | 52 | 53 | 54 | 55 | net.openhft 56 | chronicle-logger-logback 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | org.apache.maven.plugins 65 | maven-surefire-plugin 66 | 67 | 1 68 | false 69 | 70 | **/*PerfTest.java 71 | 72 | 73 | ${project.build.directory} 74 | 75 | 76 | 77 | 85 | 86 | org.apache.servicemix.tooling 87 | depends-maven-plugin 88 | 89 | 90 | generate-depends-file 91 | 92 | generate-depends-file 93 | 94 | 95 | 96 | 97 | 98 | org.apache.felix 99 | maven-bundle-plugin 100 | true 101 | 102 | 103 | ${project.groupId}.${project.artifactId} 104 | OpenHFT :: ${project.artifactId} 105 | ${project.version} 106 | net.openhft.chronicle.logger.tools.* 107 | 108 | 109 | 110 | 114 | 115 | 116 | manifest 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 126 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 127 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 128 | master 129 | 130 | 131 | 132 | -------------------------------------------------------------------------------- /logger-tools/src/main/java/net/openhft/chronicle/logger/tools/ChroniCat.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.tools; 19 | 20 | import net.openhft.chronicle.wire.WireType; 21 | 22 | public final class ChroniCat { 23 | 24 | private ChroniCat() { 25 | } 26 | 27 | public static void main(String[] args) { 28 | try { 29 | 30 | if (args.length >= 1) { 31 | int i = 0; 32 | final WireType wt; 33 | if ("-w".equals(args[i])) { 34 | wt = WireType.valueOf(args[++i].trim().toUpperCase()); 35 | i++; 36 | } else { 37 | wt = WireType.BINARY_LIGHT; 38 | } 39 | 40 | ChronicleLogReader reader = new ChronicleLogReader(args[i].trim(), wt); 41 | 42 | reader.processLogs(ChronicleLogReader::printf, false); 43 | 44 | } else { 45 | System.err.println("\nUsage: ChroniCat [-w ] "); 46 | System.err.println(" - wire format, default BINARY_LIGHT"); 47 | System.err.println(" - base path of Chronicle Logs storage"); 48 | } 49 | } catch (Exception e) { 50 | e.printStackTrace(System.err); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /logger-tools/src/main/java/net/openhft/chronicle/logger/tools/ChroniTail.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.tools; 19 | 20 | import net.openhft.chronicle.wire.WireType; 21 | 22 | public final class ChroniTail { 23 | 24 | private ChroniTail() { 25 | } 26 | 27 | public static void main(String[] args) { 28 | try { 29 | 30 | if (args.length >= 1) { 31 | int i = 0; 32 | final WireType wt; 33 | if ("-w".equals(args[i++])) { 34 | wt = WireType.valueOf(args[i++].trim().toUpperCase()); 35 | } else { 36 | wt = WireType.BINARY_LIGHT; 37 | } 38 | 39 | ChronicleLogReader reader = new ChronicleLogReader(args[i].trim(), wt); 40 | 41 | reader.processLogs(ChronicleLogReader::printf, true); 42 | 43 | } else { 44 | System.err.println("\nUsage: ChroniTail [-w ] "); 45 | System.err.println(" - wire format, default BINARY_LIGHT"); 46 | System.err.println(" - base path of Chronicle Logs storage"); 47 | } 48 | } catch (Exception e) { 49 | e.printStackTrace(System.err); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /logger-tools/src/main/java/net/openhft/chronicle/logger/tools/ChronicleLogProcessor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.tools; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogLevel; 21 | import org.jetbrains.annotations.Nullable; 22 | 23 | public interface ChronicleLogProcessor { 24 | void process( 25 | final long timestamp, 26 | final ChronicleLogLevel level, 27 | final String loggerName, 28 | final String threadName, 29 | final String message, 30 | @Nullable final Throwable throwable, 31 | final Object[] args); 32 | } 33 | -------------------------------------------------------------------------------- /logger-tools/src/main/java/net/openhft/chronicle/logger/tools/ChronicleLogReader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2022 Chronicle Software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.tools; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogLevel; 21 | import net.openhft.chronicle.queue.ChronicleQueue; 22 | import net.openhft.chronicle.queue.ExcerptTailer; 23 | import net.openhft.chronicle.wire.DocumentContext; 24 | import net.openhft.chronicle.wire.Wire; 25 | import net.openhft.chronicle.wire.WireType; 26 | import org.jetbrains.annotations.NotNull; 27 | import org.jetbrains.annotations.Nullable; 28 | import org.slf4j.helpers.MessageFormatter; 29 | 30 | import java.text.SimpleDateFormat; 31 | import java.util.ArrayList; 32 | import java.util.List; 33 | 34 | /** 35 | * Generic tool allowing users to process Chronicle logs in their own way 36 | */ 37 | public class ChronicleLogReader { 38 | private static final SimpleDateFormat tsFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); 39 | private final ChronicleQueue cq; 40 | 41 | /** 42 | * Create reader with default wire type 43 | * 44 | * @param path the path to Chronicle Logs storage 45 | */ 46 | public ChronicleLogReader( 47 | @NotNull String path) { 48 | this(path, WireType.BINARY_LIGHT); 49 | } 50 | 51 | /** 52 | * @param path the path to Chronicle Logs storage 53 | * @param wireType Chronicle wire type. Must match the wire type specified in corresponding Chronicle Logger 54 | */ 55 | public ChronicleLogReader( 56 | @NotNull String path, 57 | @NotNull WireType wireType) { 58 | cq = ChronicleQueue.singleBuilder(path).wireType(wireType).build(); 59 | } 60 | 61 | /** 62 | * Simple {@link ChronicleLogProcessor} implementation. Prints formatted message to stdout 63 | */ 64 | public static void printf( 65 | long timestamp, 66 | ChronicleLogLevel level, 67 | String loggerName, 68 | String threadName, 69 | String message, 70 | @Nullable Throwable throwable, 71 | Object[] args) { 72 | 73 | message = MessageFormatter.arrayFormat(message, args).getMessage(); 74 | 75 | if (throwable == null) { 76 | System.out.printf("%s [%s] [%s] [%s] %s%n", 77 | tsFormat.format(timestamp), 78 | level.toString(), 79 | threadName, 80 | loggerName, 81 | message); 82 | 83 | } else { 84 | System.out.printf("%s [%s] [%s] [%s] %s%n%s%n", 85 | tsFormat.format(timestamp), 86 | level.toString(), 87 | threadName, 88 | loggerName, 89 | message, 90 | throwable.toString()); 91 | } 92 | } 93 | 94 | /** 95 | * Decode logs 96 | * 97 | * @param processor user-provided processor called for each log message 98 | * @param waitForIt whether to wait for more data or stop after EOF reached 99 | */ 100 | public void processLogs(@NotNull ChronicleLogProcessor processor, boolean waitForIt) { 101 | ExcerptTailer tailer = cq.createTailer(); 102 | for (; ; ) { 103 | try (DocumentContext dc = tailer.readingDocument()) { 104 | Wire wire = dc.wire(); 105 | if (wire == null) 106 | if (waitForIt) { 107 | try { 108 | Thread.sleep(50L); 109 | } catch (InterruptedException ignored) { 110 | 111 | } 112 | continue; 113 | } else { 114 | break; 115 | } 116 | 117 | long timestamp = wire.read("ts").int64(); 118 | ChronicleLogLevel level = wire.read("level").asEnum(ChronicleLogLevel.class); 119 | String threadName = wire.read("threadName").text(); 120 | String loggerName = wire.read("loggerName").text(); 121 | String message = wire.read("message").text(); 122 | Throwable th = wire.hasMore() ? wire.read("throwable").throwable(false) : null; 123 | List argsL = new ArrayList<>(); 124 | if (wire.hasMore()) { 125 | wire.read("args").sequence(argsL, (l, vi) -> { 126 | while (vi.hasNextSequenceItem()) { 127 | l.add(vi.object(Object.class)); 128 | } 129 | }); 130 | } 131 | Object[] args = argsL.toArray(new Object[argsL.size()]); 132 | processor.process(timestamp, level, threadName, loggerName, message, th, args); 133 | } 134 | } 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /logger-tools/src/main/java/net/openhft/chronicle/logger/tools/internal/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This package and any and all sub-packages contains strictly internal classes for this Chronicle library. 3 | * Internal classes shall never be used directly. 4 | * 5 | * Specifically, the following actions (including, but not limited to) are not allowed 6 | * on internal classes and packages: 7 | * 8 | * Casting to 9 | * Reflection of any kind 10 | * Explicit Serialize/deserialize 11 | * 12 | * 13 | * The classes in this package and any sub-package are subject to 14 | * changes at any time for any reason. 15 | */ 16 | package net.openhft.chronicle.logger.tools.internal; 17 | -------------------------------------------------------------------------------- /logger-tools/src/test/java/net/openhft/chronicle/logger/tools/ChronicleLogReaderTest.java: -------------------------------------------------------------------------------- 1 | package net.openhft.chronicle.logger.tools; 2 | 3 | import net.openhft.chronicle.core.OS; 4 | import net.openhft.chronicle.core.util.Time; 5 | import net.openhft.chronicle.wire.WireType; 6 | import org.junit.Before; 7 | import org.junit.Test; 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | 11 | public class ChronicleLogReaderTest { 12 | @Before 13 | public void setup() { 14 | System.setProperty( 15 | "logback.configurationFile", 16 | System.getProperty("resources.path") 17 | + "/logback-chronicle-binary-appender.xml"); 18 | } 19 | 20 | @Test 21 | public void readTest() { 22 | final Logger logger = LoggerFactory.getLogger("binary-chronicle"); 23 | logger.info("test {} {} {}", 1, 100L, 100.123D); 24 | logger.info("test {} {} {}", 2, 100L, 100.123D); 25 | logger.info("test {} {} {}", 3, 100L, 100.123D); 26 | 27 | ChronicleLogReader reader = new ChronicleLogReader(OS.getTarget() + "/chronicle-logback/binary-chronicle" + Time.uniqueId(), WireType.BINARY_LIGHT); 28 | reader.processLogs(ChronicleLogReader::printf, false); 29 | 30 | //ChroniCat.main(new String[] {OS.getTarget() + "/chronicle-logback/binary-chronicle"}); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /logger-tools/src/test/resources/logback-chronicle-binary-appender.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 22 | 23 | 25 | 26 | %d %contextName [%t] %level %logger{36} - %msg%n 27 | 28 | 29 | 31 | ${java.io.tmpdir}/chronicle-logback/binary-chronicle 32 | false 33 | false 34 | 35 | 128 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 4.0.0 22 | 23 | 24 | net.openhft 25 | java-parent-pom 26 | 1.27ea1 27 | 28 | 29 | 30 | chronicle-logger 31 | 4.27ea2-SNAPSHOT 32 | pom 33 | 34 | OpenHFT/Chronicle-Logger 35 | OpenHFT :: High Performance Logging 36 | 37 | 38 | 39 | 40 | net.openhft 41 | third-party-bom 42 | 3.27ea2 43 | pom 44 | import 45 | 46 | 47 | 48 | net.openhft 49 | chronicle-bom 50 | 2.27ea-SNAPSHOT 51 | pom 52 | import 53 | 54 | 55 | 56 | 57 | net.openhft 58 | chronicle-logger-core 59 | ${project.version} 60 | 61 | 62 | 63 | net.openhft 64 | chronicle-logger-logback 65 | ${project.version} 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | net.openhft 75 | chronicle-core 76 | 77 | 78 | 79 | net.openhft 80 | chronicle-bytes 81 | 82 | 83 | 84 | net.openhft 85 | chronicle-queue 86 | 87 | 88 | 89 | org.jetbrains 90 | annotations 91 | 92 | 93 | 94 | 95 | org.apache.commons 96 | commons-lang3 97 | test 98 | 99 | 100 | junit 101 | junit 102 | test 103 | 104 | 105 | 106 | 107 | org.openjdk.jmh 108 | jmh-core 109 | test 110 | 111 | 112 | org.openjdk.jmh 113 | jmh-core-benchmarks 114 | test 115 | 116 | 117 | 118 | 119 | logger-core 120 | logger-jul 121 | logger-jcl 122 | logger-slf4j 123 | logger-slf4j-2 124 | logger-logback 125 | logger-log4j-1 126 | logger-log4j-2 127 | logger-tools 128 | benchmark 129 | 130 | 131 | 132 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 133 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 134 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 135 | master 136 | 137 | 138 | 139 | 140 | --------------------------------------------------------------------------------
5 | * Specifically, the following actions (including, but not limited to) are not allowed 6 | * on internal classes and packages: 7 | *
13 | * The classes in this package and any sub-package are subject to 14 | * changes at any time for any reason. 15 | */ 16 | package net.openhft.chronicle.logger.internal; 17 | -------------------------------------------------------------------------------- /logger-core/src/test/java/net/openhft/chronicle/logger/DefaultChronicleLogWriterTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger; 19 | 20 | import net.openhft.chronicle.core.OS; 21 | import net.openhft.chronicle.core.io.IOTools; 22 | import net.openhft.chronicle.core.util.Time; 23 | import net.openhft.chronicle.queue.ChronicleQueue; 24 | import net.openhft.chronicle.queue.ExcerptTailer; 25 | import net.openhft.chronicle.wire.DocumentContext; 26 | import net.openhft.chronicle.wire.Wire; 27 | import org.junit.After; 28 | import org.junit.Before; 29 | import org.junit.Test; 30 | 31 | import java.nio.file.Files; 32 | import java.nio.file.Path; 33 | import java.nio.file.Paths; 34 | import java.util.ArrayList; 35 | import java.util.List; 36 | 37 | import static java.lang.System.currentTimeMillis; 38 | import static org.junit.Assert.*; 39 | 40 | public class DefaultChronicleLogWriterTest { 41 | 42 | String baseBath; 43 | 44 | @After 45 | public void cleanup() { 46 | IOTools.deleteDirWithFiles(this.baseBath); 47 | } 48 | 49 | @Before 50 | public void setUp() throws Exception { 51 | Path path = Paths.get(OS.getTarget(), "chronicle-logger-" + Time.uniqueId()); 52 | Files.createDirectories(path); 53 | this.baseBath = path.toString(); 54 | } 55 | 56 | @Test 57 | public void testWrite() { 58 | try (final ChronicleQueue cq = ChronicleQueue.singleBuilder(this.baseBath).build()) { 59 | ChronicleLogWriter lw = new DefaultChronicleLogWriter(cq); 60 | lw.write( 61 | ChronicleLogLevel.ERROR, 62 | currentTimeMillis(), 63 | Thread.currentThread().getName(), 64 | this.getClass().getCanonicalName(), 65 | "Test message", 66 | new Exception("Test exception"), 67 | 10, 68 | 12.1 69 | ); 70 | 71 | lw.write( 72 | ChronicleLogLevel.DEBUG, 73 | currentTimeMillis(), 74 | Thread.currentThread().getName(), 75 | this.getClass().getCanonicalName(), 76 | "Test debug message" 77 | ); 78 | 79 | } 80 | 81 | try (final ChronicleQueue cq = ChronicleQueue.singleBuilder(this.baseBath).build()) { 82 | ExcerptTailer tailer = cq.createTailer(); 83 | try (DocumentContext dc = tailer.readingDocument()) { 84 | Wire wire = dc.wire(); 85 | assertNotNull(wire); 86 | assertTrue(wire.read("ts").int64() <= currentTimeMillis()); 87 | assertEquals(ChronicleLogLevel.ERROR, wire.read("level").asEnum(ChronicleLogLevel.class)); 88 | assertEquals(Thread.currentThread().getName(), wire.read("threadName").text()); 89 | assertEquals(this.getClass().getCanonicalName(), wire.read("loggerName").text()); 90 | assertEquals("Test message", wire.read("message").text()); 91 | assertEquals("Test exception", wire.read("throwable").throwable(false).getMessage()); 92 | List args = new ArrayList<>(); 93 | assertTrue(wire.hasMore()); 94 | wire.read("args").sequence(args, (l, vi) -> { 95 | while (vi.hasNextSequenceItem()) { 96 | l.add(vi.object(Object.class)); 97 | } 98 | }); 99 | assertArrayEquals(new Object[]{10, 12.1}, args.toArray(new Object[args.size()])); 100 | } 101 | 102 | try (DocumentContext dc = tailer.readingDocument()) { 103 | Wire wire = dc.wire(); 104 | assertNotNull(wire); 105 | assertTrue(wire.read("ts").int64() <= currentTimeMillis()); 106 | assertEquals(ChronicleLogLevel.DEBUG, wire.read("level").asEnum(ChronicleLogLevel.class)); 107 | assertEquals(Thread.currentThread().getName(), wire.read("threadName").text()); 108 | assertEquals(this.getClass().getCanonicalName(), wire.read("loggerName").text()); 109 | assertEquals("Test debug message", wire.read("message").text()); 110 | assertFalse(wire.hasMore()); 111 | } 112 | try (DocumentContext dc = tailer.readingDocument()) { 113 | Wire wire = dc.wire(); 114 | assertNull(wire); 115 | } 116 | } 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /logger-jcl/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 22 | 23 | 4.0.0 24 | 25 | 26 | net.openhft 27 | chronicle-logger 28 | 4.27ea2-SNAPSHOT 29 | ../pom.xml 30 | 31 | 32 | OpenHFT/Chronicle-Logger/logger-jcl 33 | chronicle-logger-jcl 34 | bundle 35 | 36 | 37 | 38 | net.openhft 39 | chronicle-logger-core 40 | 41 | 42 | 43 | 44 | commons-logging 45 | commons-logging 46 | 47 | 48 | 49 | 50 | org.slf4j 51 | slf4j-api 52 | test 53 | 54 | 55 | org.slf4j 56 | slf4j-nop 57 | test 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | org.apache.maven.plugins 66 | maven-surefire-plugin 67 | 68 | 69 | ${project.build.directory} 70 | 71 | STDOUT 72 | 73 | 74 | 75 | **/*PerfTest.java 76 | 77 | 78 | 79 | 87 | 88 | org.apache.servicemix.tooling 89 | depends-maven-plugin 90 | 91 | 92 | generate-depends-file 93 | 94 | generate-depends-file 95 | 96 | 97 | 98 | 99 | 100 | org.apache.felix 101 | maven-bundle-plugin 102 | true 103 | 104 | 105 | ${project.groupId}.${project.artifactId} 106 | OpenHFT :: ${project.artifactId} 107 | ${project.version} 108 | net.openhft.chronicle.logger.jcl.* 109 | 110 | 111 | 112 | 116 | 117 | 118 | manifest 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 128 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 129 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 130 | master 131 | 132 | 133 | 134 | -------------------------------------------------------------------------------- /logger-jcl/src/main/java/net/openhft/chronicle/logger/jcl/ChronicleLoggerFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.jcl; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogConfig; 21 | import net.openhft.chronicle.logger.ChronicleLogLevel; 22 | import net.openhft.chronicle.logger.ChronicleLogManager; 23 | import org.apache.commons.logging.Log; 24 | import org.apache.commons.logging.LogConfigurationException; 25 | import org.apache.commons.logging.LogFactory; 26 | import org.apache.commons.logging.impl.NoOpLog; 27 | 28 | import java.io.IOException; 29 | import java.util.Map; 30 | import java.util.concurrent.ConcurrentHashMap; 31 | 32 | public class ChronicleLoggerFactory extends LogFactory { 33 | private static final Log NOP_LOGGER = new NoOpLog(); 34 | 35 | private final Map loggers; 36 | private final ChronicleLogManager manager; 37 | 38 | public ChronicleLoggerFactory() { 39 | logRawDiagnostic("[CHRONICLE] Initialize ChronicleLoggerFactory"); 40 | 41 | this.loggers = new ConcurrentHashMap<>(); 42 | this.manager = ChronicleLogManager.getInstance(); 43 | 44 | logRawDiagnostic("[CHRONICLE] ChronicleLoggerFactory initialized"); 45 | } 46 | 47 | @Override 48 | public void release() { 49 | this.loggers.clear(); 50 | this.manager.clear(); 51 | } 52 | 53 | @Override 54 | public Object getAttribute(String s) { 55 | return null; 56 | } 57 | 58 | @Override 59 | public void setAttribute(String s, Object o) { 60 | } 61 | 62 | @Override 63 | public String[] getAttributeNames() { 64 | return new String[0]; 65 | } 66 | 67 | @Override 68 | public void removeAttribute(String s) { 69 | } 70 | 71 | @SuppressWarnings("rawtypes") 72 | @Override 73 | public Log getInstance(Class type) throws LogConfigurationException { 74 | return getInstance(type.getName()); 75 | } 76 | 77 | @Override 78 | public Log getInstance(String name) throws LogConfigurationException { 79 | try { 80 | return getLogger(name); 81 | } catch (Exception e) { 82 | System.err.println("Unable to initialise chronicle-jcl (" + name + ")\n " + e.getMessage()); 83 | } 84 | 85 | return NOP_LOGGER; 86 | } 87 | 88 | // ************************************************************************* 89 | // 90 | // ************************************************************************* 91 | 92 | private synchronized Log getLogger(String name) throws IOException { 93 | ChronicleLogger logger = loggers.get(name); 94 | if (logger == null) { 95 | loggers.put( 96 | name, 97 | logger = new ChronicleLogger( 98 | manager.getWriter(name), 99 | name, 100 | ChronicleLogLevel.fromStringLevel( 101 | manager.cfg().getString(name, ChronicleLogConfig.KEY_LEVEL) 102 | ) 103 | ) 104 | ); 105 | } 106 | 107 | return logger; 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /logger-jcl/src/main/java/net/openhft/chronicle/logger/jcl/internal/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This package and any and all sub-packages contains strictly internal classes for this Chronicle library. 3 | * Internal classes shall never be used directly. 4 | * 5 | * Specifically, the following actions (including, but not limited to) are not allowed 6 | * on internal classes and packages: 7 | * 8 | * Casting to 9 | * Reflection of any kind 10 | * Explicit Serialize/deserialize 11 | * 12 | * 13 | * The classes in this package and any sub-package are subject to 14 | * changes at any time for any reason. 15 | */ 16 | package net.openhft.chronicle.logger.jcl.internal; 17 | -------------------------------------------------------------------------------- /logger-jcl/src/main/resources/META-INF/services/org.apache.commons.logging.LogFactory: -------------------------------------------------------------------------------- 1 | net.openhft.chronicle.logger.jcl.ChronicleLoggerFactory -------------------------------------------------------------------------------- /logger-jcl/src/test/java/net/openhft/chronicle/logger/jcl/JclTestBase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.jcl; 19 | 20 | import net.openhft.chronicle.core.OS; 21 | import net.openhft.chronicle.core.util.Time; 22 | import net.openhft.chronicle.logger.ChronicleLogLevel; 23 | import org.apache.commons.logging.Log; 24 | 25 | class JclTestBase { 26 | 27 | // ************************************************************************* 28 | // 29 | // ************************************************************************* 30 | 31 | static final ChronicleLogLevel[] LOG_LEVELS = ChronicleLogLevel.values(); 32 | 33 | static String basePath() { 34 | String path = System.getProperty("java.io.tmpdir"); 35 | String sep = System.getProperty("file.separator"); 36 | 37 | if (!path.endsWith(sep)) { 38 | path += sep; 39 | } 40 | 41 | return path + "chronicle-jcl"; 42 | } 43 | 44 | static String basePath(String loggerName) { 45 | return basePath() + System.getProperty("file.separator") + loggerName; 46 | } 47 | 48 | static void log(Log logger, ChronicleLogLevel level, String message) { 49 | switch (level) { 50 | case TRACE: 51 | logger.trace(message); 52 | break; 53 | 54 | case DEBUG: 55 | logger.debug(message); 56 | break; 57 | 58 | case INFO: 59 | logger.info(message); 60 | break; 61 | 62 | case WARN: 63 | logger.warn(message); 64 | break; 65 | 66 | case ERROR: 67 | logger.error(message); 68 | break; 69 | default: 70 | throw new UnsupportedOperationException(); 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /logger-jcl/src/test/resources/chronicle.logger.properties: -------------------------------------------------------------------------------- 1 | 2 | # 3 | # Copyright (C) 2014-2017 Chronicle Software 4 | # 5 | # https://chronicle.software 6 | # 7 | # This program is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU Lesser General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License. 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 14 | # GNU 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, see . 18 | # 19 | 20 | ################################################################################ 21 | # Common 22 | ################################################################################ 23 | 24 | chronicle.logger.base = ${java.io.tmpdir}/chronicle-jcl 25 | chronicle.logger.root.path = ${chronicle.logger.base}/root 26 | chronicle.logger.root.level = debug 27 | chronicle.logger.root.append = false 28 | 29 | ################################################################################ 30 | # Loggers 31 | ################################################################################ 32 | 33 | # logger : Logger1 34 | chronicle.logger.logger_1.path = ${chronicle.logger.base}/logger_1 35 | chronicle.logger.logger_1.level = info 36 | chronicle.logger.logger_1.wireType = JSON 37 | 38 | # logger : impl 39 | chronicle.logger.readwrite.path = ${chronicle.logger.base}/readwrite 40 | -------------------------------------------------------------------------------- /logger-jul/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 22 | 23 | 4.0.0 24 | 25 | 26 | net.openhft 27 | chronicle-logger 28 | 4.27ea2-SNAPSHOT 29 | ../pom.xml 30 | 31 | 32 | OpenHFT/Chronicle-Logger/logger-jul 33 | chronicle-logger-jul 34 | bundle 35 | 36 | 37 | 38 | net.openhft 39 | chronicle-logger-core 40 | 41 | 42 | org.slf4j 43 | slf4j-nop 44 | test 45 | 46 | 47 | 48 | 49 | 50 | 51 | org.apache.maven.plugins 52 | maven-surefire-plugin 53 | 54 | 1 55 | false 56 | 57 | **/*PerfTest.java 58 | 59 | 60 | ${project.build.directory} 61 | 62 | ${project.basedir}/src/test/resources 63 | 64 | 65 | 66 | 67 | 75 | 76 | org.apache.servicemix.tooling 77 | depends-maven-plugin 78 | 79 | 80 | generate-depends-file 81 | 82 | generate-depends-file 83 | 84 | 85 | 86 | 87 | 88 | org.apache.felix 89 | maven-bundle-plugin 90 | true 91 | 92 | 93 | ${project.groupId}.${project.artifactId} 94 | OpenHFT :: ${project.artifactId} 95 | ${project.version} 96 | net.openhft.chronicle.logger.jul.* 97 | 98 | 99 | 100 | 104 | 105 | 106 | manifest 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 115 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 116 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 117 | master 118 | 119 | 120 | -------------------------------------------------------------------------------- /logger-jul/src/main/java/net/openhft/chronicle/logger/jul/AbstractChronicleHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.jul; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogWriter; 21 | 22 | import java.io.IOException; 23 | import java.util.logging.Filter; 24 | import java.util.logging.Handler; 25 | import java.util.logging.Level; 26 | import java.util.logging.LogRecord; 27 | 28 | abstract class AbstractChronicleHandler extends Handler { 29 | 30 | private String path; 31 | private ChronicleLogWriter writer; 32 | 33 | protected AbstractChronicleHandler() { 34 | this.path = null; 35 | this.writer = null; 36 | } 37 | 38 | @Override 39 | public void flush() { 40 | } 41 | 42 | @Override 43 | public void close() throws SecurityException { 44 | if (this.writer != null) { 45 | try { 46 | this.writer.close(); 47 | } catch (IOException e) { 48 | // Ignore 49 | } 50 | } 51 | } 52 | 53 | @Override 54 | public void publish(final LogRecord record) { 55 | if ((writer != null) && isLoggable(record)) { 56 | doPublish(record, this.writer); 57 | } 58 | } 59 | 60 | // ************************************************************************* 61 | // 62 | // ************************************************************************* 63 | 64 | protected abstract void doPublish(final LogRecord record, final ChronicleLogWriter writer); 65 | 66 | protected final void setWriter(ChronicleLogWriter appender) { 67 | this.writer = appender; 68 | } 69 | 70 | @Override 71 | public final void setFilter(Filter newFilter) { 72 | super.setFilter(newFilter); 73 | } 74 | 75 | @Override 76 | public final synchronized void setLevel(Level newLevel) { 77 | super.setLevel(newLevel); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /logger-jul/src/main/java/net/openhft/chronicle/logger/jul/ChronicleHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.jul; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogWriter; 21 | import net.openhft.chronicle.logger.DefaultChronicleLogWriter; 22 | import net.openhft.chronicle.logger.LogAppenderConfig; 23 | 24 | import java.io.IOException; 25 | import java.util.logging.Level; 26 | import java.util.logging.LogRecord; 27 | 28 | import static net.openhft.chronicle.logger.ChronicleLogConfig.KEY_WIRETYPE; 29 | 30 | public class ChronicleHandler extends AbstractChronicleHandler { 31 | 32 | @SuppressWarnings("this-escape") 33 | public ChronicleHandler() throws IOException { 34 | ChronicleHandlerConfig handlerCfg = new ChronicleHandlerConfig(getClass()); 35 | String appenderPath = handlerCfg.getString("path", null); 36 | LogAppenderConfig appenderCfg = handlerCfg.getAppenderConfig(); 37 | 38 | setLevel(handlerCfg.getLevel("level", Level.ALL)); 39 | setFilter(handlerCfg.getFilter("filter", null)); 40 | 41 | setWriter(new DefaultChronicleLogWriter(appenderCfg.build( 42 | appenderPath, 43 | handlerCfg.getStringProperty(KEY_WIRETYPE, "BINARY_LIGHT")) 44 | )); 45 | } 46 | 47 | @SuppressWarnings("deprecation") 48 | @Override 49 | protected void doPublish(final LogRecord record, final ChronicleLogWriter writer) { 50 | writer.write( 51 | ChronicleHelper.getLogLevel(record), 52 | record.getMillis(), 53 | "thread-" + record.getThreadID(), 54 | record.getLoggerName(), 55 | record.getMessage(), 56 | record.getThrown(), 57 | record.getParameters()); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /logger-jul/src/main/java/net/openhft/chronicle/logger/jul/ChronicleHelper.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.jul; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogLevel; 21 | 22 | import java.util.HashMap; 23 | import java.util.Map; 24 | import java.util.logging.Level; 25 | import java.util.logging.LogRecord; 26 | 27 | class ChronicleHelper { 28 | 29 | private static final Map julToCHronicleLevelMap; 30 | private static final Map chronicleToJulLevelMap; 31 | 32 | static { 33 | julToCHronicleLevelMap = new HashMap<>(); 34 | julToCHronicleLevelMap.put(Level.ALL, ChronicleLogLevel.TRACE); 35 | julToCHronicleLevelMap.put(Level.FINEST, ChronicleLogLevel.TRACE); 36 | julToCHronicleLevelMap.put(Level.FINER, ChronicleLogLevel.TRACE); 37 | julToCHronicleLevelMap.put(Level.FINE, ChronicleLogLevel.DEBUG); 38 | julToCHronicleLevelMap.put(Level.CONFIG, ChronicleLogLevel.DEBUG); 39 | julToCHronicleLevelMap.put(Level.INFO, ChronicleLogLevel.INFO); 40 | julToCHronicleLevelMap.put(Level.WARNING, ChronicleLogLevel.WARN); 41 | julToCHronicleLevelMap.put(Level.SEVERE, ChronicleLogLevel.ERROR); 42 | 43 | chronicleToJulLevelMap = new HashMap<>(); 44 | chronicleToJulLevelMap.put(ChronicleLogLevel.TRACE, Level.FINER); 45 | chronicleToJulLevelMap.put(ChronicleLogLevel.DEBUG, Level.FINE); 46 | chronicleToJulLevelMap.put(ChronicleLogLevel.INFO, Level.INFO); 47 | chronicleToJulLevelMap.put(ChronicleLogLevel.WARN, Level.WARNING); 48 | chronicleToJulLevelMap.put(ChronicleLogLevel.ERROR, Level.SEVERE); 49 | } 50 | 51 | private ChronicleHelper() { 52 | 53 | } 54 | 55 | static ChronicleLogLevel getLogLevel(final LogRecord julRecord) { 56 | return getLogLevel(julRecord.getLevel()); 57 | } 58 | 59 | static ChronicleLogLevel getLogLevel(final Level julLevel) { 60 | ChronicleLogLevel level = julToCHronicleLevelMap.get(julLevel); 61 | return level != null ? level : ChronicleLogLevel.DEBUG; 62 | } 63 | 64 | static Level getLogLevel(final ChronicleLogLevel chronicleLevel) { 65 | Level level = chronicleToJulLevelMap.get(chronicleLevel); 66 | return level != null ? level : Level.FINE; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /logger-jul/src/main/java/net/openhft/chronicle/logger/jul/ChronicleLoggerManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.jul; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogManager; 21 | import net.openhft.chronicle.logger.ChronicleLogWriter; 22 | 23 | import java.io.IOException; 24 | import java.util.Collections; 25 | import java.util.Enumeration; 26 | import java.util.Map; 27 | import java.util.concurrent.ConcurrentHashMap; 28 | import java.util.logging.LogManager; 29 | import java.util.logging.Logger; 30 | 31 | public class ChronicleLoggerManager extends LogManager { 32 | 33 | private final Map loggers; 34 | private final ChronicleLogManager manager; 35 | 36 | public ChronicleLoggerManager() { 37 | this.loggers = new ConcurrentHashMap<>(); 38 | this.manager = ChronicleLogManager.getInstance(); 39 | } 40 | 41 | @Override 42 | public boolean addLogger(final Logger logger) { 43 | return false; 44 | } 45 | 46 | @Override 47 | public Logger getLogger(final String name) { 48 | try { 49 | return doGetLogger(name); 50 | } catch (Exception e) { 51 | System.err.println("Unable to initialize chronicle-logger-jul (" + name + ")\n " + e.getMessage()); 52 | } 53 | 54 | return ChronicleLogger.Null.INSTANCE; 55 | } 56 | 57 | @Override 58 | public Enumeration getLoggerNames() { 59 | return Collections.enumeration(this.loggers.keySet()); 60 | } 61 | 62 | @Override 63 | public void reset() throws SecurityException { 64 | this.loggers.clear(); 65 | this.manager.clear(); 66 | } 67 | 68 | // ************************************************************************* 69 | // 70 | // ************************************************************************* 71 | 72 | private synchronized Logger doGetLogger(String name) throws IOException { 73 | Logger logger = loggers.get(name); 74 | if (logger == null) { 75 | final ChronicleLogWriter writer = manager.getWriter(name); 76 | logger = new ChronicleLogger( 77 | writer, 78 | name, 79 | manager.cfg().getLevel(name)); 80 | loggers.put(name, logger); 81 | } 82 | 83 | return logger; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /logger-jul/src/main/java/net/openhft/chronicle/logger/jul/internal/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This package and any and all sub-packages contains strictly internal classes for this Chronicle library. 3 | * Internal classes shall never be used directly. 4 | * 5 | * Specifically, the following actions (including, but not limited to) are not allowed 6 | * on internal classes and packages: 7 | * 8 | * Casting to 9 | * Reflection of any kind 10 | * Explicit Serialize/deserialize 11 | * 12 | * 13 | * The classes in this package and any sub-package are subject to 14 | * changes at any time for any reason. 15 | */ 16 | package net.openhft.chronicle.logger.jul.internal; 17 | -------------------------------------------------------------------------------- /logger-jul/src/test/java/net/openhft/chronicle/logger/jul/JulHandlerTestBase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.jul; 19 | 20 | import net.openhft.chronicle.core.OS; 21 | import net.openhft.chronicle.core.util.Time; 22 | 23 | import java.io.File; 24 | import java.io.FileInputStream; 25 | import java.io.IOException; 26 | import java.util.logging.LogManager; 27 | 28 | import static org.junit.Assert.assertNotNull; 29 | import static org.junit.Assert.assertTrue; 30 | 31 | public class JulHandlerTestBase extends JulTestBase { 32 | 33 | // ************************************************************************* 34 | // 35 | // ************************************************************************* 36 | 37 | protected static String rootPath() { 38 | String path = System.getProperty("java.io.tmpdir"); 39 | String sep = System.getProperty("file.separator"); 40 | 41 | if (!path.endsWith(sep)) { 42 | path += sep; 43 | } 44 | 45 | return path + "chronicle-jul"; 46 | } 47 | 48 | protected static String basePath(String type) { 49 | return rootPath() 50 | + System.getProperty("file.separator") 51 | + type; 52 | } 53 | 54 | /** 55 | * @param id the id of the logger 56 | * @throws IOException if an I/O error occurs 57 | */ 58 | protected void setupLogManager(String id) throws IOException { 59 | String cfgPath = System.getProperty("resources.path"); 60 | File cfgFile = new File(cfgPath, id + ".properties"); 61 | 62 | assertNotNull(cfgPath); 63 | assertTrue(cfgFile.exists()); 64 | 65 | LogManager manager = LogManager.getLogManager(); 66 | manager.reset(); 67 | manager.readConfiguration(new FileInputStream(cfgFile)); 68 | } 69 | 70 | // ************************************************************************* 71 | // 72 | // ************************************************************************* 73 | 74 | } 75 | -------------------------------------------------------------------------------- /logger-jul/src/test/java/net/openhft/chronicle/logger/jul/JulLoggerTestBase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.jul; 19 | 20 | import net.openhft.chronicle.core.OS; 21 | import net.openhft.chronicle.core.util.Time; 22 | 23 | import java.util.logging.LogManager; 24 | 25 | class JulLoggerTestBase extends JulTestBase { 26 | 27 | // ************************************************************************* 28 | // 29 | // ************************************************************************* 30 | 31 | static String basePath() { 32 | String path = System.getProperty("java.io.tmpdir"); 33 | String sep = System.getProperty("file.separator"); 34 | 35 | if (!path.endsWith(sep)) { 36 | path += sep; 37 | } 38 | 39 | return path + "chronicle-jul-api"; 40 | } 41 | 42 | static String basePath(String loggerName) { 43 | return basePath() 44 | + System.getProperty("file.separator") 45 | + loggerName; 46 | } 47 | 48 | // ************************************************************************* 49 | // 50 | // ************************************************************************* 51 | 52 | static void setupLogger(Class> testName) { 53 | setupLogger(testName.getSimpleName()); 54 | } 55 | 56 | static void setupLogger(String id) { 57 | System.setProperty( 58 | "java.util.logging.manager", 59 | ChronicleLoggerManager.class.getName()); 60 | System.setProperty( 61 | "sun.util.logging.disableCallerCheck", 62 | "false"); 63 | System.setProperty( 64 | "chronicle.logger.properties", 65 | id.endsWith(".properties") ? id : id + ".properties"); 66 | 67 | LogManager.getLogManager().reset(); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /logger-jul/src/test/java/net/openhft/chronicle/logger/jul/JulTestBase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.jul; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogLevel; 21 | 22 | import java.util.logging.Level; 23 | import java.util.logging.Logger; 24 | 25 | public class JulTestBase { 26 | 27 | protected static final ChronicleLogLevel[] LOG_LEVELS = ChronicleLogLevel.values(); 28 | 29 | // ************************************************************************* 30 | // 31 | // ************************************************************************* 32 | 33 | protected static void log(Logger logger, ChronicleLogLevel level, String fmt, Object... args) { 34 | switch (level) { 35 | case TRACE: 36 | logger.log(Level.FINER, fmt, args); 37 | break; 38 | 39 | case DEBUG: 40 | logger.log(Level.FINE, fmt, args); 41 | break; 42 | 43 | case INFO: 44 | logger.log(Level.INFO, fmt, args); 45 | break; 46 | 47 | case WARN: 48 | logger.log(Level.WARNING, fmt, args); 49 | break; 50 | 51 | case ERROR: 52 | logger.log(Level.SEVERE, fmt, args); 53 | break; 54 | default: 55 | throw new UnsupportedOperationException(); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /logger-jul/src/test/resources/JulLoggerChronicleTest.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2014-2017 Chronicle Software 3 | # 4 | # https://chronicle.software 5 | # 6 | # This program is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License 16 | # along with this program. If not, see . 17 | # 18 | 19 | ################################################################################ 20 | # Common 21 | ################################################################################ 22 | 23 | chronicle.logger.base = ${java.io.tmpdir}/chronicle-jul-api 24 | 25 | chronicle.logger.root.path = ${chronicle.logger.base}/root-binary 26 | chronicle.logger.root.level = debug 27 | chronicle.logger.root.append = false 28 | 29 | chronicle.logger.logger_1.path = ${chronicle.logger.base}/logger_1 30 | chronicle.logger.logger_1.level = info 31 | chronicle.logger.logger_1.wireType = json 32 | 33 | chronicle.logger.logger_bin.path = ${chronicle.logger.base}/logger_bin 34 | chronicle.logger.logger_bin.level = trace 35 | -------------------------------------------------------------------------------- /logger-jul/src/test/resources/binary-cfg.properties: -------------------------------------------------------------------------------- 1 | 2 | # 3 | # Copyright (C) 2014-2017 Chronicle Software 4 | # 5 | # https://chronicle.software 6 | # 7 | # This program is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU Lesser General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License. 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 14 | # GNU 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, see . 18 | # 19 | 20 | handlers=java.util.logging.ConsoleHandler, net.openhft.chronicle.logger.jul.ChronicleHandler 21 | 22 | .level=ALL 23 | 24 | java.util.logging.ConsoleHandler.level=ALL 25 | java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter 26 | 27 | net.openhft.level=WARNING 28 | net.openhft.handlers=java.util.logging.ConsoleHandler 29 | 30 | ################################################################################ 31 | # BINARY 32 | ################################################################################ 33 | 34 | net.openhft.chronicle.logger.jul.ChronicleHandler.path = ${java.io.tmpdir}/chronicle-jul 35 | net.openhft.chronicle.logger.jul.ChronicleHandler.level = ALL 36 | 37 | binary-cfg.level=INFO 38 | binary-cfg.handlers=net.openhft.chronicle.logger.jul.ChronicleHandler 39 | binary-cfg.useParentHandlers=false 40 | -------------------------------------------------------------------------------- /logger-jul/src/test/resources/binary-chronicle.properties: -------------------------------------------------------------------------------- 1 | 2 | # 3 | # Copyright (C) 2014-2017 Chronicle Software 4 | # 5 | # https://chronicle.software 6 | # 7 | # This program is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU Lesser General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License. 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 14 | # GNU 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, see . 18 | # 19 | 20 | handlers=java.util.logging.ConsoleHandler, net.openhft.chronicle.logger.jul.ChronicleHandler 21 | 22 | .level=ALL 23 | 24 | java.util.logging.ConsoleHandler.level=ALL 25 | java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter 26 | 27 | net.openhft.level=WARNING 28 | net.openhft.handlers=java.util.logging.ConsoleHandler 29 | 30 | ################################################################################ 31 | # BINARY 32 | ################################################################################ 33 | 34 | net.openhft.chronicle.logger.jul.ChronicleHandler.path = ${java.io.tmpdir}/chronicle-jul/binary-chronicle 35 | net.openhft.chronicle.logger.jul.ChronicleHandler.level = ALL 36 | 37 | binary-chronicle.level=ALL 38 | binary-chronicle.handlers=net.openhft.chronicle.logger.jul.ChronicleHandler 39 | binary-chronicle.useParentHandlers=false 40 | 41 | -------------------------------------------------------------------------------- /logger-log4j-1/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 22 | 23 | 4.0.0 24 | 25 | 26 | net.openhft 27 | chronicle-logger 28 | 4.27ea2-SNAPSHOT 29 | ../pom.xml 30 | 31 | 32 | OpenHFT/Chronicle-Logger/logger-log4j-1 33 | chronicle-logger-log4j-1 34 | bundle 35 | 36 | 37 | 38 | net.openhft 39 | chronicle-logger-core 40 | 41 | 42 | 43 | 44 | org.slf4j 45 | slf4j-api 46 | 47 | 48 | org.slf4j 49 | slf4j-log4j12 50 | 1.7.33 51 | 52 | 53 | 54 | 55 | log4j 56 | log4j 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | org.apache.maven.plugins 65 | maven-surefire-plugin 66 | 67 | 1 68 | false 69 | 70 | **/*PerfTest.java 71 | 72 | 73 | ${project.build.directory} 74 | 75 | 76 | 77 | 85 | 86 | org.apache.servicemix.tooling 87 | depends-maven-plugin 88 | 89 | 90 | generate-depends-file 91 | 92 | generate-depends-file 93 | 94 | 95 | 96 | 97 | 98 | org.apache.felix 99 | maven-bundle-plugin 100 | true 101 | 102 | 103 | ${project.groupId}.${project.artifactId} 104 | OpenHFT :: ${project.artifactId} 105 | ${project.version} 106 | net.openhft.chronicle.logger.log4j1.* 107 | 108 | 109 | 110 | 114 | 115 | 116 | manifest 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 126 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 127 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 128 | master 129 | 130 | 131 | 132 | -------------------------------------------------------------------------------- /logger-log4j-1/src/main/java/net/openhft/chronicle/logger/log4j1/ChronicleAppender.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.log4j1; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogWriter; 21 | import net.openhft.chronicle.logger.DefaultChronicleLogWriter; 22 | import net.openhft.chronicle.logger.LogAppenderConfig; 23 | 24 | import java.io.IOException; 25 | 26 | public final class ChronicleAppender extends AbstractChronicleAppender { 27 | 28 | private final LogAppenderConfig config; 29 | 30 | public ChronicleAppender() { 31 | this.config = new LogAppenderConfig(); 32 | } 33 | 34 | // ************************************************************************* 35 | // Custom logging options 36 | // ************************************************************************* 37 | 38 | public void setBlockSize(int blockSize) { 39 | config.setBlockSize(blockSize); 40 | } 41 | 42 | public void setBufferCapacity(int bufferCapacity) { 43 | config.setBufferCapacity(bufferCapacity); 44 | } 45 | 46 | public String rollCycle() { 47 | return config.getRollCycle(); 48 | } 49 | 50 | public void rollCycle(String rollCycle) { 51 | config.setRollCycle(rollCycle); 52 | } 53 | 54 | @Override 55 | protected ChronicleLogWriter createWriter() throws IOException { 56 | return new DefaultChronicleLogWriter(this.config.build(this.getPath(), this.getWireType())); 57 | } 58 | 59 | // ************************************************************************* 60 | // LogAppenderConfig 61 | // ************************************************************************* 62 | 63 | LogAppenderConfig getChronicleConfig() { 64 | return this.config; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /logger-log4j-1/src/main/java/net/openhft/chronicle/logger/log4j1/internal/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This package and any and all sub-packages contains strictly internal classes for this Chronicle library. 3 | * Internal classes shall never be used directly. 4 | * 5 | * Specifically, the following actions (including, but not limited to) are not allowed 6 | * on internal classes and packages: 7 | * 8 | * Casting to 9 | * Reflection of any kind 10 | * Explicit Serialize/deserialize 11 | * 12 | * 13 | * The classes in this package and any sub-package are subject to 14 | * changes at any time for any reason. 15 | */ 16 | package net.openhft.chronicle.logger.log4j1.internal; 17 | -------------------------------------------------------------------------------- /logger-log4j-1/src/test/java/net/openhft/chronicle/logger/log4j1/Log4j1TestBase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.log4j1; 19 | 20 | import net.openhft.chronicle.core.OS; 21 | import net.openhft.chronicle.core.util.Time; 22 | import net.openhft.chronicle.logger.ChronicleLogLevel; 23 | import org.slf4j.Logger; 24 | 25 | import java.io.File; 26 | 27 | class Log4j1TestBase { 28 | 29 | // ************************************************************************* 30 | // 31 | // ************************************************************************* 32 | 33 | static final ChronicleLogLevel[] LOG_LEVELS = ChronicleLogLevel.values(); 34 | 35 | static String rootPath() { 36 | String path = System.getProperty("java.io.tmpdir"); 37 | String sep = System.getProperty("file.separator"); 38 | 39 | if (!path.endsWith(sep)) { 40 | path += sep; 41 | } 42 | 43 | return path + "chronicle-log4j1"; 44 | } 45 | 46 | static String basePath(String type) { 47 | return rootPath() 48 | + File.separator 49 | + type; 50 | } 51 | 52 | static void log(Logger logger, ChronicleLogLevel level, String fmt, Object... args) { 53 | switch (level) { 54 | case TRACE: 55 | logger.trace(fmt, args); 56 | break; 57 | 58 | case DEBUG: 59 | logger.debug(fmt, args); 60 | break; 61 | 62 | case INFO: 63 | logger.info(fmt, args); 64 | break; 65 | 66 | case WARN: 67 | logger.warn(fmt, args); 68 | break; 69 | 70 | case ERROR: 71 | logger.error(fmt, args); 72 | break; 73 | default: 74 | throw new UnsupportedOperationException(); 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /logger-log4j-1/src/test/resources/log4j.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /logger-log4j-2/src/main/java/net/openhft/chronicle/logger/log4j2/ChronicleAppender.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.log4j2; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogWriter; 21 | import net.openhft.chronicle.logger.DefaultChronicleLogWriter; 22 | import net.openhft.chronicle.logger.LogAppenderConfig; 23 | import org.apache.logging.log4j.core.Filter; 24 | import org.apache.logging.log4j.core.LogEvent; 25 | import org.apache.logging.log4j.core.config.plugins.Plugin; 26 | import org.apache.logging.log4j.core.config.plugins.PluginAttribute; 27 | import org.apache.logging.log4j.core.config.plugins.PluginElement; 28 | import org.apache.logging.log4j.core.config.plugins.PluginFactory; 29 | import org.jetbrains.annotations.NotNull; 30 | 31 | import java.io.IOException; 32 | 33 | @Plugin( 34 | name = "Chronicle", 35 | category = "Core", 36 | elementType = "appender", 37 | printObject = true) 38 | public class ChronicleAppender extends AbstractChronicleAppender { 39 | 40 | private final ChronicleCfg config; 41 | 42 | public ChronicleAppender(final String name, final Filter filter, final String path, final String wireType, final ChronicleCfg config) { 43 | super(name, filter, path, wireType); 44 | 45 | this.config = config != null ? config : new ChronicleCfg(); 46 | } 47 | 48 | // ************************************************************************* 49 | // 50 | // ************************************************************************* 51 | 52 | @PluginFactory 53 | public static ChronicleAppender createAppender( 54 | @PluginAttribute("name") final String name, 55 | @PluginAttribute("path") final String path, 56 | @PluginAttribute("wireType") final String wireType, 57 | @PluginElement("chronicleCfg") final ChronicleCfg chronicleConfig, 58 | @PluginElement("filter") final Filter filter) { 59 | if (name == null) { 60 | LOGGER.error("No name provided for ChronicleAppender"); 61 | return null; 62 | } 63 | 64 | if (path == null) { 65 | LOGGER.error("No path provided for ChronicleAppender"); 66 | return null; 67 | } 68 | 69 | return new ChronicleAppender(name, filter, path, wireType, chronicleConfig); 70 | } 71 | 72 | @Override 73 | public void doAppend(@NotNull final LogEvent event, @NotNull final ChronicleLogWriter writer) { 74 | writer.write( 75 | toChronicleLogLevel(event.getLevel()), 76 | event.getTimeMillis(), 77 | event.getThreadName(), 78 | event.getLoggerName(), 79 | event.getMessage().getFormattedMessage(), 80 | event.getThrown() 81 | ); 82 | } 83 | 84 | @Override 85 | protected ChronicleLogWriter createWriter() throws IOException { 86 | return new DefaultChronicleLogWriter(config.build(getPath(), getWireType())); 87 | } 88 | 89 | // ************************************************************************* 90 | // 91 | // ************************************************************************* 92 | 93 | protected LogAppenderConfig getChronicleConfig() { 94 | return this.config; 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /logger-log4j-2/src/main/java/net/openhft/chronicle/logger/log4j2/internal/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This package and any and all sub-packages contains strictly internal classes for this Chronicle library. 3 | * Internal classes shall never be used directly. 4 | * 5 | * Specifically, the following actions (including, but not limited to) are not allowed 6 | * on internal classes and packages: 7 | * 8 | * Casting to 9 | * Reflection of any kind 10 | * Explicit Serialize/deserialize 11 | * 12 | * 13 | * The classes in this package and any sub-package are subject to 14 | * changes at any time for any reason. 15 | */ 16 | package net.openhft.chronicle.logger.log4j2.internal; 17 | -------------------------------------------------------------------------------- /logger-log4j-2/src/test/java/net/openhft/chronicle/logger/log4j2/Log4j2TestBase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.log4j2; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogLevel; 21 | import org.apache.logging.log4j.LogManager; 22 | import org.slf4j.Logger; 23 | 24 | import java.io.File; 25 | 26 | public class Log4j2TestBase { 27 | 28 | // ************************************************************************* 29 | // 30 | // ************************************************************************* 31 | 32 | static final ChronicleLogLevel[] LOG_LEVELS = ChronicleLogLevel.values(); 33 | 34 | static String rootPath() { 35 | String path = System.getProperty("java.io.tmpdir"); 36 | String sep = System.getProperty("file.separator"); 37 | 38 | if (!path.endsWith(sep)) { 39 | path += sep; 40 | } 41 | 42 | return path + "chronicle-log4j2"; 43 | } 44 | 45 | static String basePath(String type) { 46 | return rootPath() 47 | + File.separator 48 | + type; 49 | } 50 | 51 | static void log(Logger logger, ChronicleLogLevel level, String fmt, Object... args) { 52 | switch (level) { 53 | case TRACE: 54 | logger.trace(fmt, args); 55 | break; 56 | 57 | case DEBUG: 58 | logger.debug(fmt, args); 59 | break; 60 | 61 | case INFO: 62 | logger.info(fmt, args); 63 | break; 64 | 65 | case WARN: 66 | logger.warn(fmt, args); 67 | break; 68 | 69 | case ERROR: 70 | logger.error(fmt, args); 71 | break; 72 | default: 73 | throw new UnsupportedOperationException(); 74 | } 75 | } 76 | 77 | // ************************************************************************* 78 | // 79 | // ************************************************************************* 80 | 81 | static org.apache.logging.log4j.core.Appender getAppender(String name) { 82 | final org.apache.logging.log4j.core.LoggerContext ctx = 83 | (org.apache.logging.log4j.core.LoggerContext) LogManager.getContext(); 84 | 85 | return ctx.getConfiguration().getAppender(name); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /logger-log4j-2/src/test/java/net/openhft/chronicle/logger/log4j2/Log4j2VulnerabilityTest.java: -------------------------------------------------------------------------------- 1 | package net.openhft.chronicle.logger.log4j2; 2 | 3 | import org.apache.logging.log4j.LogManager; 4 | import org.junit.BeforeClass; 5 | import org.junit.Test; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | 9 | import java.io.IOException; 10 | import java.nio.file.Files; 11 | import java.nio.file.Paths; 12 | 13 | /** 14 | * see https://blog.cloudflare.com/inside-the-log4j2-vulnerability-cve-2021-44228/ etc. 15 | * 16 | * This is not a proper unit test - just some exploratory code 17 | */ 18 | public class Log4j2VulnerabilityTest extends Log4j2TestBase { 19 | 20 | public static final String VULNERABILITY = "${jndi:ldap://localhost/xxxx}"; 21 | 22 | @BeforeClass 23 | public static void systemProperties() { 24 | System.setProperty("com.sun.jndi.rmi.object.trustURLCodebase", "true"); 25 | } 26 | 27 | /** 28 | * Run this test with -Dlog4j2.debug and you will not see any JNDI-related logging - see below 29 | */ 30 | @Test 31 | public void testVulnerability() throws IOException { 32 | final String testId = "chronicle"; 33 | final String threadId = testId + "-th"; 34 | final Logger logger = LoggerFactory.getLogger(testId); 35 | 36 | Thread.currentThread().setName(threadId); 37 | Files.createDirectories(Paths.get(basePath(testId))); 38 | 39 | logger.error(VULNERABILITY); 40 | } 41 | 42 | /** 43 | * Run this test with -Dlog4j2.debug and you will see 44 | * 45 | * {@code WARN StatusLogger Error looking up JNDI resource [ldap://localhost/xxxx]} 46 | * 47 | */ 48 | @Test 49 | public void testVulnerabilityLog4j2() { 50 | LogManager.getLogger("HelloWorld").error(VULNERABILITY); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /logger-log4j-2/src/test/resources/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | ${sys:java.io.tmpdir}/chronicle-log4j2/conf-chronicle 34 | 35 | 128 36 | 256 37 | 38 | 39 | 40 | 41 | ${sys:java.io.tmpdir}/chronicle-log4j2/chronicle 42 | 43 | FAST_HOURLY 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /logger-logback/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 22 | 23 | 4.0.0 24 | 25 | 26 | net.openhft 27 | chronicle-logger 28 | 4.27ea2-SNAPSHOT 29 | ../pom.xml 30 | 31 | 32 | OpenHFT/Chronicle-Logger/logger-logback 33 | chronicle-logger-logback 34 | bundle 35 | 36 | 37 | 38 | net.openhft 39 | chronicle-logger-core 40 | 41 | 42 | 43 | 44 | org.slf4j 45 | slf4j-api 46 | 47 | 48 | 49 | 50 | ch.qos.logback 51 | logback-classic 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | org.apache.maven.plugins 60 | maven-surefire-plugin 61 | 62 | 1 63 | false 64 | 65 | **/*PerfTest.java 66 | 67 | 68 | 69 | ${project.basedir}/src/test/resources 70 | 71 | ${project.build.directory} 72 | 73 | 74 | 75 | 83 | 84 | org.apache.servicemix.tooling 85 | depends-maven-plugin 86 | 87 | 88 | generate-depends-file 89 | 90 | generate-depends-file 91 | 92 | 93 | 94 | 95 | 96 | org.apache.felix 97 | maven-bundle-plugin 98 | true 99 | 100 | 101 | ${project.groupId}.${project.artifactId} 102 | OpenHFT :: ${project.artifactId} 103 | ${project.version} 104 | net.openhft.chronicle.logger.logback.* 105 | 106 | 107 | 108 | 112 | 113 | 114 | manifest 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 123 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 124 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 125 | master 126 | 127 | 128 | -------------------------------------------------------------------------------- /logger-logback/src/main/java/net/openhft/chronicle/logger/logback/AbstractChronicleAppender.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.logback; 19 | 20 | import ch.qos.logback.classic.Level; 21 | import ch.qos.logback.classic.spi.ILoggingEvent; 22 | import ch.qos.logback.core.Appender; 23 | import ch.qos.logback.core.filter.Filter; 24 | import ch.qos.logback.core.spi.ContextAwareBase; 25 | import ch.qos.logback.core.spi.FilterAttachableImpl; 26 | import ch.qos.logback.core.spi.FilterReply; 27 | import net.openhft.chronicle.logger.ChronicleLogLevel; 28 | import net.openhft.chronicle.logger.ChronicleLogWriter; 29 | 30 | import java.io.IOException; 31 | import java.util.List; 32 | 33 | public abstract class AbstractChronicleAppender 34 | extends ContextAwareBase 35 | implements Appender { 36 | 37 | private final FilterAttachableImpl filterAttachable; 38 | protected ChronicleLogWriter writer; 39 | private String name; 40 | private boolean started; 41 | private String path; 42 | private String wireType; 43 | 44 | protected AbstractChronicleAppender() { 45 | this.filterAttachable = new FilterAttachableImpl<>(); 46 | this.name = null; 47 | this.started = false; 48 | this.path = null; 49 | this.wireType = null; 50 | this.writer = null; 51 | } 52 | 53 | // ************************************************************************* 54 | // Custom logging options 55 | // ************************************************************************* 56 | 57 | public static ChronicleLogLevel toChronicleLogLevel(final Level level) { 58 | switch (level.levelInt) { 59 | case Level.DEBUG_INT: 60 | return ChronicleLogLevel.DEBUG; 61 | case Level.TRACE_INT: 62 | return ChronicleLogLevel.TRACE; 63 | case Level.INFO_INT: 64 | return ChronicleLogLevel.INFO; 65 | case Level.WARN_INT: 66 | return ChronicleLogLevel.WARN; 67 | case Level.ERROR_INT: 68 | return ChronicleLogLevel.ERROR; 69 | default: 70 | throw new IllegalArgumentException(level.levelInt + " not a valid level value"); 71 | } 72 | } 73 | 74 | public String getPath() { 75 | return this.path; 76 | } 77 | 78 | public void setPath(String path) { 79 | this.path = path; 80 | } 81 | 82 | public String getWireType() { 83 | return wireType; 84 | } 85 | 86 | // ************************************************************************* 87 | // Chronicle implementation 88 | // ************************************************************************* 89 | 90 | public void setWireType(String wireType) { 91 | this.wireType = wireType; 92 | } 93 | 94 | protected abstract ChronicleLogWriter createWriter() throws IOException; 95 | 96 | // ************************************************************************* 97 | // 98 | // ************************************************************************* 99 | 100 | protected abstract void doAppend(final ILoggingEvent event, final ChronicleLogWriter writer); 101 | 102 | @Override 103 | public String getName() { 104 | return name; 105 | } 106 | 107 | @Override 108 | public void setName(String name) { 109 | this.name = name; 110 | } 111 | 112 | @Override 113 | public boolean isStarted() { 114 | return started; 115 | } 116 | 117 | @Override 118 | public void addFilter(Filter newFilter) { 119 | this.filterAttachable.addFilter(newFilter); 120 | } 121 | 122 | @Override 123 | public void clearAllFilters() { 124 | this.filterAttachable.clearAllFilters(); 125 | } 126 | 127 | @Override 128 | public List> getCopyOfAttachedFiltersList() { 129 | return this.filterAttachable.getCopyOfAttachedFiltersList(); 130 | } 131 | 132 | @Override 133 | public FilterReply getFilterChainDecision(ILoggingEvent event) { 134 | return this.filterAttachable.getFilterChainDecision(event); 135 | } 136 | 137 | @Override 138 | public void start() { 139 | if (getPath() == null) { 140 | addError("Appender " + getName() + " has configuration errors and is not started!"); 141 | 142 | } else { 143 | try { 144 | this.writer = createWriter(); 145 | this.started = true; 146 | } catch (IOException e) { 147 | this.writer = null; 148 | addError("Appender " + getName() + " " + e.getMessage()); 149 | } 150 | } 151 | } 152 | 153 | @Override 154 | public void stop() { 155 | if (this.writer != null) { 156 | try { 157 | this.writer.close(); 158 | } catch (IOException e) { 159 | addError("Appender " + getName() + " " + e.getMessage()); 160 | } 161 | } 162 | 163 | this.started = false; 164 | } 165 | 166 | // ************************************************************************* 167 | // 168 | // ************************************************************************* 169 | 170 | @Override 171 | public void doAppend(final ILoggingEvent event) { 172 | if (getFilterChainDecision(event) != FilterReply.DENY) { 173 | doAppend(event, writer); 174 | } 175 | } 176 | } 177 | -------------------------------------------------------------------------------- /logger-logback/src/main/java/net/openhft/chronicle/logger/logback/ChronicleAppender.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.logback; 19 | 20 | import ch.qos.logback.classic.spi.ILoggingEvent; 21 | import ch.qos.logback.classic.spi.ThrowableProxy; 22 | import ch.qos.logback.core.joran.spi.DefaultClass; 23 | import net.openhft.chronicle.logger.ChronicleLogWriter; 24 | import net.openhft.chronicle.logger.DefaultChronicleLogWriter; 25 | import net.openhft.chronicle.logger.LogAppenderConfig; 26 | 27 | import java.io.IOException; 28 | 29 | public class ChronicleAppender extends AbstractChronicleAppender { 30 | 31 | private boolean includeCallerData; 32 | private boolean includeMDC; 33 | 34 | private LogAppenderConfig config; 35 | 36 | public ChronicleAppender() { 37 | super(); 38 | 39 | this.includeCallerData = true; 40 | this.includeMDC = true; 41 | this.config = new LogAppenderConfig(); 42 | } 43 | 44 | public LogAppenderConfig getChronicleConfig() { 45 | return this.config; 46 | } 47 | 48 | @DefaultClass(value = LogAppenderConfig.class) 49 | public void setChronicleConfig(final LogAppenderConfig config) { 50 | this.config = config; 51 | } 52 | 53 | @Override 54 | protected ChronicleLogWriter createWriter() throws IOException { 55 | return new DefaultChronicleLogWriter(this.config.build(this.getPath(), getWireType())); 56 | } 57 | 58 | // ************************************************************************* 59 | // Custom logging options 60 | // ************************************************************************* 61 | 62 | public boolean isIncludeCallerData() { 63 | return this.includeCallerData; 64 | } 65 | 66 | public void setIncludeCallerData(boolean logCallerData) { 67 | this.includeCallerData = logCallerData; 68 | } 69 | 70 | public boolean isIncludeMappedDiagnosticContext() { 71 | return this.includeMDC; 72 | } 73 | 74 | public void setIncludeMappedDiagnosticContext(boolean logMDC) { 75 | this.includeMDC = logMDC; 76 | } 77 | 78 | // ************************************************************************* 79 | // 80 | // ************************************************************************* 81 | 82 | @Override 83 | public void doAppend(final ILoggingEvent event, final ChronicleLogWriter writer) { 84 | final ThrowableProxy tp = (ThrowableProxy) event.getThrowableProxy(); 85 | 86 | writer.write( 87 | toChronicleLogLevel(event.getLevel()), 88 | event.getTimeStamp(), 89 | event.getThreadName(), 90 | event.getLoggerName(), 91 | event.getMessage(), 92 | tp != null ? tp.getThrowable() : null, 93 | event.getArgumentArray() 94 | ); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /logger-logback/src/main/java/net/openhft/chronicle/logger/logback/internal/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This package and any and all sub-packages contains strictly internal classes for this Chronicle library. 3 | * Internal classes shall never be used directly. 4 | * 5 | * Specifically, the following actions (including, but not limited to) are not allowed 6 | * on internal classes and packages: 7 | * 8 | * Casting to 9 | * Reflection of any kind 10 | * Explicit Serialize/deserialize 11 | * 12 | * 13 | * The classes in this package and any sub-package are subject to 14 | * changes at any time for any reason. 15 | */ 16 | package net.openhft.chronicle.logger.logback.internal; 17 | -------------------------------------------------------------------------------- /logger-logback/src/test/java/net/openhft/chronicle/logger/logback/LogbackChronicleProgrammaticConfigTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.logback; 19 | 20 | import ch.qos.logback.classic.Logger; 21 | import ch.qos.logback.classic.LoggerContext; 22 | import net.openhft.chronicle.core.OS; 23 | import net.openhft.chronicle.core.util.Time; 24 | import net.openhft.chronicle.logger.LogAppenderConfig; 25 | import org.junit.Test; 26 | import org.slf4j.LoggerFactory; 27 | 28 | public class LogbackChronicleProgrammaticConfigTest extends LogbackTestBase { 29 | 30 | @Test 31 | public void testConfig() { 32 | LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory(); 33 | context.reset(); 34 | 35 | ChronicleAppender appender = new ChronicleAppender(); 36 | appender.setPath(OS.getTarget() + "/clog" + Time.uniqueId()); 37 | appender.setChronicleConfig(new LogAppenderConfig()); 38 | appender.setContext(context); 39 | appender.start(); 40 | 41 | Logger logger = context.getLogger(Logger.ROOT_LOGGER_NAME); 42 | logger.addAppender(appender); 43 | 44 | logger.info("Hello World"); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /logger-logback/src/test/java/net/openhft/chronicle/logger/logback/LogbackIndexedChronicleConfigTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.logback; 19 | 20 | import ch.qos.logback.classic.spi.ILoggingEvent; 21 | import org.junit.Before; 22 | import org.junit.Test; 23 | 24 | import java.io.IOException; 25 | 26 | import static org.junit.Assert.*; 27 | 28 | public class LogbackIndexedChronicleConfigTest extends LogbackTestBase { 29 | 30 | @Before 31 | public void setup() { 32 | System.setProperty( 33 | "logback.configurationFile", 34 | System.getProperty("resources.path") + "/logback-chronicle-config.xml" 35 | ); 36 | } 37 | 38 | // ************************************************************************* 39 | // 40 | // ************************************************************************* 41 | 42 | @Test 43 | public void testBinaryIndexedChronicleAppenderConfig() throws IOException { 44 | final String loggerName = "config-binary-chronicle"; 45 | final String appenderName = "CONFIG-BINARY-CHRONICLE"; 46 | 47 | final ch.qos.logback.classic.Logger logger = getLoggerContext().getLogger(loggerName); 48 | assertNotNull(logger); 49 | 50 | final ch.qos.logback.core.Appender appender = logger.getAppender(appenderName); 51 | assertNotNull(appender); 52 | assertTrue(appender instanceof ChronicleAppender); 53 | 54 | ChronicleAppender ba = (ChronicleAppender) appender; 55 | assertEquals(128, ba.getChronicleConfig().getBlockSize()); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /logger-logback/src/test/java/net/openhft/chronicle/logger/logback/LogbackTestBase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.logback; 19 | 20 | import ch.qos.logback.classic.LoggerContext; 21 | import net.openhft.chronicle.core.OS; 22 | import net.openhft.chronicle.core.util.Time; 23 | import net.openhft.chronicle.logger.ChronicleLogLevel; 24 | import org.slf4j.Logger; 25 | import org.slf4j.LoggerFactory; 26 | 27 | public class LogbackTestBase { 28 | 29 | // ************************************************************************* 30 | // 31 | // ************************************************************************* 32 | 33 | static final ChronicleLogLevel[] LOG_LEVELS = ChronicleLogLevel.values(); 34 | 35 | static String rootPath() { 36 | String path = System.getProperty("java.io.tmpdir"); 37 | String sep = System.getProperty("file.separator"); 38 | 39 | if (!path.endsWith(sep)) { 40 | path += sep; 41 | } 42 | 43 | return path + "chronicle-logback"; 44 | } 45 | 46 | static String basePath(String type) { 47 | return rootPath() 48 | + System.getProperty("file.separator") 49 | + type; 50 | } 51 | 52 | static void log(Logger logger, ChronicleLogLevel level, String fmt, Object... args) { 53 | switch (level) { 54 | case TRACE: 55 | logger.trace(fmt, args); 56 | break; 57 | 58 | case DEBUG: 59 | logger.debug(fmt, args); 60 | break; 61 | 62 | case INFO: 63 | logger.info(fmt, args); 64 | break; 65 | 66 | case WARN: 67 | logger.warn(fmt, args); 68 | break; 69 | 70 | case ERROR: 71 | logger.error(fmt, args); 72 | break; 73 | default: 74 | throw new UnsupportedOperationException(); 75 | } 76 | } 77 | 78 | // ************************************************************************* 79 | // 80 | // ************************************************************************* 81 | 82 | LoggerContext getLoggerContext() { 83 | return (LoggerContext) LoggerFactory.getILoggerFactory(); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /logger-logback/src/test/resources/logback-chronicle-binary-appender.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 22 | 23 | 25 | 26 | %d %contextName [%t] %level %logger{36} - %msg%n 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 36 | ${java.io.tmpdir}/chronicle-logback/binary-chronicle 37 | false 38 | false 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /logger-logback/src/test/resources/logback-chronicle-config.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 22 | 23 | 25 | 26 | %d %contextName [%t] %level %logger{36} - %msg%n 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 36 | ${java.io.tmpdir}/chronicle-logback/config-binary-chronicle 37 | false 38 | false 39 | 40 | 41 | 128 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /logger-slf4j-2/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 22 | 23 | 4.0.0 24 | 25 | 26 | net.openhft 27 | chronicle-logger 28 | 4.27ea2-SNAPSHOT 29 | ../pom.xml 30 | 31 | 32 | OpenHFT/Chronicle-Logger/logger-slf4j-2 33 | chronicle-logger-slf4j-2 34 | bundle 35 | 36 | 37 | 38 | net.openhft 39 | chronicle-logger-core 40 | 41 | 42 | 43 | 44 | org.slf4j 45 | slf4j-api 46 | 2.0.0 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | org.apache.maven.plugins 55 | maven-surefire-plugin 56 | 57 | 58 | **/*PerfTest.java 59 | 60 | 61 | ${project.build.directory} 62 | 63 | 64 | 65 | 73 | 74 | org.apache.servicemix.tooling 75 | depends-maven-plugin 76 | 77 | 78 | generate-depends-file 79 | 80 | generate-depends-file 81 | 82 | 83 | 84 | 85 | 86 | org.apache.felix 87 | maven-bundle-plugin 88 | true 89 | 90 | 91 | ${project.groupId}.${project.artifactId} 92 | OpenHFT :: ${project.artifactId} 93 | ${project.version} 94 | net.openhft.chronicle.logger.slf4j.* 95 | 96 | 97 | 98 | 102 | 103 | 104 | manifest 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 114 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 115 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 116 | master 117 | 118 | 119 | 120 | -------------------------------------------------------------------------------- /logger-slf4j-2/src/main/java/net/openhft/chronicle/logger/slf4j2/ChronicleLoggerFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.slf4j2; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogManager; 21 | import net.openhft.chronicle.logger.ChronicleLogWriter; 22 | import org.slf4j.ILoggerFactory; 23 | import org.slf4j.Logger; 24 | import org.slf4j.helpers.NOPLogger; 25 | import org.slf4j.impl.SimpleLogger; 26 | 27 | import java.util.Map; 28 | import java.util.concurrent.ConcurrentHashMap; 29 | 30 | /** 31 | * Simple implementation of Logger that sends all enabled slf4j messages, 32 | * for all defined loggers, to one or more VanillaChronicle.. 33 | * 34 | * To configure this sl4j binding you need to specify the location of a properties 35 | * files via system properties: 36 | * {@code -Dchronicle.logger.properties=${pathOfYourPropertiesFile}} 37 | * 38 | * The following system properties are supported to configure the behavior of this 39 | * logger: 40 | * 41 | * {@code chronicle.logger.root.path} 42 | * {@code chronicle.logger.root.level} 43 | * {@code chronicle.logger.root.append} 44 | * 45 | */ 46 | public class ChronicleLoggerFactory implements ILoggerFactory { 47 | private final Map loggers; 48 | private final ChronicleLogManager manager; 49 | 50 | // ************************************************************************* 51 | // 52 | // ************************************************************************* 53 | 54 | /** 55 | * c-tor 56 | */ 57 | public ChronicleLoggerFactory() { 58 | this.loggers = new ConcurrentHashMap<>(); 59 | this.manager = ChronicleLogManager.getInstance(); 60 | } 61 | 62 | // ************************************************************************* 63 | // for testing 64 | // ************************************************************************* 65 | 66 | /** 67 | * Return an appropriate {@link ChronicleLogger} instance by name. 68 | */ 69 | @Override 70 | public Logger getLogger(String name) { 71 | try { 72 | return doGetLogger(name); 73 | } catch (Exception e) { 74 | System.err.println("Unable to initialize chronicle-logger-slf4j (" + name + ")\n " + e.getMessage()); 75 | e.printStackTrace(); 76 | } 77 | 78 | return NOPLogger.NOP_LOGGER; 79 | } 80 | 81 | // ************************************************************************* 82 | // 83 | // ************************************************************************* 84 | 85 | synchronized void reload() { 86 | this.loggers.clear(); 87 | this.manager.reload(); 88 | } 89 | 90 | private synchronized Logger doGetLogger(String name) { 91 | Logger logger = loggers.get(name); 92 | if (logger == null) { 93 | if (name != null && name.startsWith("net.openhft")) { 94 | SimpleLogger.lazyInit(); 95 | logger = new SimpleLogger(name); 96 | } else { 97 | final ChronicleLogWriter writer = manager.getWriter(name); 98 | logger = new ChronicleLogger(writer, name, manager.cfg().getLevel(name)); 99 | } 100 | loggers.put(name, logger); 101 | } 102 | 103 | return logger; 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /logger-slf4j-2/src/main/java/net/openhft/chronicle/logger/slf4j2/internal/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This package and any and all sub-packages contains strictly internal classes for this Chronicle library. 3 | * Internal classes shall never be used directly. 4 | * 5 | * Specifically, the following actions (including, but not limited to) are not allowed 6 | * on internal classes and packages: 7 | * 8 | * Casting to 9 | * Reflection of any kind 10 | * Explicit Serialize/deserialize 11 | * 12 | * 13 | * The classes in this package and any sub-package are subject to 14 | * changes at any time for any reason. 15 | */ 16 | package net.openhft.chronicle.logger.slf4j2.internal; 17 | -------------------------------------------------------------------------------- /logger-slf4j-2/src/main/java/org/slf4j/impl/ChronicleServiceProvider.java: -------------------------------------------------------------------------------- 1 | package org.slf4j.impl; 2 | 3 | import net.openhft.chronicle.logger.slf4j2.ChronicleLoggerFactory; 4 | import org.slf4j.ILoggerFactory; 5 | import org.slf4j.IMarkerFactory; 6 | import org.slf4j.helpers.BasicMarkerFactory; 7 | import org.slf4j.helpers.NOPMDCAdapter; 8 | import org.slf4j.spi.MDCAdapter; 9 | import org.slf4j.spi.SLF4JServiceProvider; 10 | 11 | public class ChronicleServiceProvider implements SLF4JServiceProvider { 12 | 13 | /** 14 | * Declare the version of the SLF4J API this implementation is compiled against. 15 | * The value of this field is modified with each major release. 16 | */ 17 | // to avoid constant folding by the compiler, this field must *not* be final 18 | public static String REQUESTED_API_VERSION = "2.0.99"; // !final 19 | 20 | public ChronicleServiceProvider() {} 21 | /** 22 | * The ILoggerFactory instance returned by the {@link #getLoggerFactory} 23 | * method should always be the same object 24 | */ 25 | private ILoggerFactory loggerFactory; 26 | 27 | private IMarkerFactory markerFactory; 28 | private MDCAdapter mdcAdapter; 29 | 30 | @Override 31 | public ILoggerFactory getLoggerFactory() { 32 | return loggerFactory; 33 | } 34 | 35 | @Override 36 | public IMarkerFactory getMarkerFactory() { 37 | return markerFactory; 38 | } 39 | 40 | @Override 41 | public MDCAdapter getMDCAdapter() { 42 | return mdcAdapter; 43 | } 44 | 45 | @Override 46 | public String getRequestedApiVersion() { 47 | return REQUESTED_API_VERSION; 48 | } 49 | 50 | @Override 51 | public void initialize() { 52 | loggerFactory = new ChronicleLoggerFactory(); 53 | markerFactory = new BasicMarkerFactory(); 54 | mdcAdapter = new NOPMDCAdapter(); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /logger-slf4j-2/src/main/java/org/slf4j/impl/OutputChoice.java: -------------------------------------------------------------------------------- 1 | package org.slf4j.impl; 2 | 3 | import java.io.PrintStream; 4 | 5 | /** 6 | * This class encapsulates the user's choice of output target. 7 | * 8 | * @author Ceki Gülcü 9 | * 10 | */ 11 | class OutputChoice { 12 | 13 | enum OutputChoiceType { 14 | SYS_OUT, CACHED_SYS_OUT, SYS_ERR, CACHED_SYS_ERR, FILE; 15 | } 16 | 17 | final OutputChoiceType outputChoiceType; 18 | final PrintStream targetPrintStream; 19 | 20 | OutputChoice(OutputChoiceType outputChoiceType) { 21 | if (outputChoiceType == OutputChoiceType.FILE) { 22 | throw new IllegalArgumentException(); 23 | } 24 | this.outputChoiceType = outputChoiceType; 25 | if (outputChoiceType == OutputChoiceType.CACHED_SYS_OUT) { 26 | this.targetPrintStream = System.out; 27 | } else if (outputChoiceType == OutputChoiceType.CACHED_SYS_ERR) { 28 | this.targetPrintStream = System.err; 29 | } else { 30 | this.targetPrintStream = null; 31 | } 32 | } 33 | 34 | OutputChoice(PrintStream printStream) { 35 | this.outputChoiceType = OutputChoiceType.FILE; 36 | this.targetPrintStream = printStream; 37 | } 38 | 39 | PrintStream getTargetPrintStream() { 40 | switch (outputChoiceType) { 41 | case SYS_OUT: 42 | return System.out; 43 | case SYS_ERR: 44 | return System.err; 45 | case CACHED_SYS_ERR: 46 | case CACHED_SYS_OUT: 47 | case FILE: 48 | return targetPrintStream; 49 | default: 50 | throw new IllegalArgumentException(); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /logger-slf4j-2/src/main/resources/META-INF/services/org.slf4j.spi.SLF4JServiceProvider: -------------------------------------------------------------------------------- 1 | org.slf4j.impl.ChronicleServiceProvider 2 | -------------------------------------------------------------------------------- /logger-slf4j-2/src/test/java/net/openhft/chronicle/logger/slf4j2/ChronicleLoggingConfigTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.slf4j2; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogConfig; 21 | import org.junit.Test; 22 | 23 | import static org.junit.Assert.assertNotNull; 24 | 25 | public class ChronicleLoggingConfigTest { 26 | @Test 27 | public void testLoadClasspathIndexed() { 28 | System.setProperty("chronicle.logger.properties", "chronicle.logger.properties"); 29 | assertLoadsValidConfig(); 30 | } 31 | 32 | private void assertLoadsValidConfig() { 33 | ChronicleLogConfig config = ChronicleLogConfig.load(); 34 | assertNotNull("unable to load config", config); 35 | assertNotNull("is not a valid config", config.getAppenderConfig()); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /logger-slf4j-2/src/test/java/net/openhft/chronicle/logger/slf4j2/Slf4jChronicleConfigurationTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.slf4j2; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogConfig; 21 | import net.openhft.chronicle.logger.ChronicleLogLevel; 22 | import org.junit.Test; 23 | 24 | import java.io.File; 25 | import java.util.Properties; 26 | 27 | import static org.junit.Assert.assertEquals; 28 | import static org.junit.Assert.assertNotNull; 29 | 30 | public class Slf4jChronicleConfigurationTest extends Slf4jTestBase { 31 | 32 | @Test 33 | public void testLoadProperties() { 34 | final String cfgPath = "chronicle.logger.properties"; 35 | final ChronicleLogConfig cfg = ChronicleLogConfig.load(cfgPath); 36 | 37 | assertNotNull(cfg); 38 | 39 | assertEquals( 40 | new File(basePath("root")), 41 | new File(cfg.getString(ChronicleLogConfig.KEY_PATH))); 42 | assertEquals( 43 | ChronicleLogLevel.DEBUG.toString(), 44 | cfg.getString(ChronicleLogConfig.KEY_LEVEL).toUpperCase()); 45 | assertEquals("false", cfg.getString(ChronicleLogConfig.KEY_APPEND)); 46 | assertEquals( 47 | new File(basePath("logger_1")), 48 | new File(cfg.getString("logger_1", ChronicleLogConfig.KEY_PATH))); 49 | assertEquals( 50 | ChronicleLogLevel.INFO.toString(), 51 | cfg.getString("logger_1", ChronicleLogConfig.KEY_LEVEL).toUpperCase()); 52 | assertEquals( 53 | ChronicleLogLevel.DEBUG.toString(), 54 | cfg.getString("readwrite", ChronicleLogConfig.KEY_LEVEL).toUpperCase()); 55 | } 56 | 57 | @Test 58 | public void testLoadConfig() { 59 | final Properties properties = new Properties(); 60 | properties.setProperty("chronicle.logger.root.cfg.blockSize", "256"); 61 | 62 | final ChronicleLogConfig clc = ChronicleLogConfig.load(properties); 63 | assertNotNull(clc.getAppenderConfig()); 64 | 65 | assertEquals(256, clc.getAppenderConfig().getBlockSize()); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /logger-slf4j-2/src/test/java/net/openhft/chronicle/logger/slf4j2/Slf4jChronicleLoggerPerfTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.slf4j2; 19 | 20 | import net.openhft.chronicle.core.io.IOTools; 21 | import org.apache.commons.lang3.StringUtils; 22 | import org.junit.After; 23 | import org.junit.Before; 24 | import org.junit.Ignore; 25 | import org.junit.Test; 26 | import org.slf4j.Logger; 27 | import org.slf4j.LoggerFactory; 28 | 29 | import java.util.concurrent.ExecutorService; 30 | import java.util.concurrent.Executors; 31 | import java.util.concurrent.TimeUnit; 32 | 33 | @Ignore 34 | public class Slf4jChronicleLoggerPerfTest extends Slf4jTestBase { 35 | 36 | // ************************************************************************* 37 | // 38 | // ************************************************************************* 39 | 40 | @Before 41 | public void setUp() { 42 | System.setProperty( 43 | "chronicle.logger.properties", 44 | "chronicle.logger.perf.properties"); 45 | 46 | getChronicleLoggerFactory().reload(); 47 | } 48 | 49 | @After 50 | public void tearDown() { 51 | IOTools.deleteDirWithFiles(basePath()); 52 | } 53 | 54 | // ************************************************************************* 55 | // Single Thread 56 | // ************************************************************************* 57 | 58 | @Test 59 | public void testSingleThreadLogging1() { 60 | Thread.currentThread().setName("perf-plain"); 61 | 62 | final String testId = "perf-chronicle"; 63 | final Logger clogger = LoggerFactory.getLogger(testId); 64 | final long items = 1000000; 65 | 66 | warmup(clogger); 67 | 68 | for (int s = 64; s <= 1024; s += 64) { 69 | final String staticStr = StringUtils.leftPad("", s, 'X'); 70 | 71 | long cStart1 = System.nanoTime(); 72 | 73 | for (int i = 1; i <= items; i++) { 74 | clogger.info(staticStr); 75 | } 76 | 77 | long cEnd1 = System.nanoTime(); 78 | 79 | System.out.printf("items=%03d size=%04d => chronology=%.3f ms, chronology-average=%.3f us\n", 80 | items, 81 | staticStr.length(), 82 | (cEnd1 - cStart1) / 1e6, 83 | (cEnd1 - cStart1) / items / 1e3); 84 | } 85 | } 86 | 87 | @Test 88 | public void testSingleThreadLogging2() { 89 | Thread.currentThread().setName("perf-plain"); 90 | 91 | final String testId = "perf-chronicle"; 92 | final Logger clogger = LoggerFactory.getLogger(testId); 93 | final long items = 1000000; 94 | final String strFmt = StringUtils.leftPad("> v1={}, v2={}, v3={}", 32, 'X'); 95 | 96 | warmup(clogger); 97 | 98 | for (int n = 0; n < 10; n++) { 99 | long cStart1 = System.nanoTime(); 100 | 101 | for (int i = 1; i <= items; i++) { 102 | clogger.info(strFmt, i, i * 10, i / 16); 103 | } 104 | 105 | long cEnd1 = System.nanoTime(); 106 | 107 | System.out.printf("items=%03d => chronology=%.3f ms, chronology-average=%.3f us\n", 108 | items, 109 | (cEnd1 - cStart1) / 1e6, 110 | (cEnd1 - cStart1) / items / 1e3); 111 | } 112 | } 113 | 114 | // ************************************************************************* 115 | // Multi Thread 116 | // ************************************************************************* 117 | 118 | @Test 119 | public void testMultiThreadLogging() throws InterruptedException { 120 | warmup(LoggerFactory.getLogger("perf-chronicle")); 121 | 122 | final int RUNS = 1000000; 123 | final int THREADS = 10; 124 | 125 | for (int size : new int[]{64, 128, 256}) { 126 | { 127 | final long start = System.nanoTime(); 128 | 129 | ExecutorService es = Executors.newFixedThreadPool(THREADS); 130 | for (int t = 0; t < THREADS; t++) { 131 | es.submit(new RunnableLogger(RUNS, size, "perf-chronicle")); 132 | } 133 | 134 | es.shutdown(); 135 | es.awaitTermination(5, TimeUnit.SECONDS); 136 | 137 | final long time = System.nanoTime() - start; 138 | 139 | System.out.printf("ChronicleLog.MT (runs=%d, min size=%03d, elapsed=%.3f ms) took an average of %.3f us per entry\n", 140 | RUNS, 141 | size, 142 | time / 1e6, 143 | time / 1e3 / (RUNS * THREADS) 144 | ); 145 | } 146 | } 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /logger-slf4j-2/src/test/java/net/openhft/chronicle/logger/slf4j2/Slf4jTestBase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.slf4j2; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogLevel; 21 | import net.openhft.chronicle.logger.slf4j2.ChronicleLoggerFactory; 22 | import org.apache.commons.lang3.StringUtils; 23 | import org.slf4j.Logger; 24 | import org.slf4j.LoggerFactory; 25 | import org.slf4j.impl.ChronicleServiceProvider; 26 | 27 | class Slf4jTestBase { 28 | 29 | // ************************************************************************* 30 | // 31 | // ************************************************************************* 32 | 33 | static final ChronicleLogLevel[] LOG_LEVELS = ChronicleLogLevel.values(); 34 | 35 | static String basePath() { 36 | String path = System.getProperty("java.io.tmpdir"); 37 | String sep = System.getProperty("file.separator"); 38 | 39 | if (!path.endsWith(sep)) { 40 | path += sep; 41 | } 42 | 43 | return path + "chronicle-slf4j"; 44 | } 45 | 46 | static String basePath(String loggerName) { 47 | return basePath() 48 | + System.getProperty("file.separator") 49 | + loggerName; 50 | } 51 | 52 | static void log(Logger logger, ChronicleLogLevel level, String fmt, Object... args) { 53 | switch (level) { 54 | case TRACE: 55 | logger.trace(fmt, args); 56 | break; 57 | 58 | case DEBUG: 59 | logger.debug(fmt, args); 60 | break; 61 | 62 | case INFO: 63 | logger.info(fmt, args); 64 | break; 65 | 66 | case WARN: 67 | logger.warn(fmt, args); 68 | break; 69 | 70 | case ERROR: 71 | logger.error(fmt, args); 72 | break; 73 | default: 74 | throw new UnsupportedOperationException(); 75 | } 76 | } 77 | 78 | static void warmup(Logger logger) { 79 | for (int i = 0; i < 10; i++) { 80 | logger.info("warmup"); 81 | } 82 | } 83 | 84 | // ************************************************************************* 85 | // 86 | // ************************************************************************* 87 | 88 | /** 89 | * @return the ChronicleLoggerFactory singleton 90 | */ 91 | ChronicleLoggerFactory getChronicleLoggerFactory() { 92 | ChronicleServiceProvider provider = new ChronicleServiceProvider(); 93 | provider.initialize(); 94 | return (ChronicleLoggerFactory) provider.getLoggerFactory(); 95 | } 96 | 97 | // ************************************************************************* 98 | // 99 | // ************************************************************************* 100 | 101 | protected final class RunnableLogger implements Runnable { 102 | private final Logger logger; 103 | private final int runs; 104 | private final String fmt; 105 | private final String fmtBase = " > val1={}, val2={}, val3={}"; 106 | 107 | public RunnableLogger(int runs, int pad, String loggerName) { 108 | this.logger = LoggerFactory.getLogger(loggerName); 109 | this.runs = runs; 110 | this.fmt = StringUtils.rightPad(fmtBase, pad + fmtBase.length() - (4 + 8 + 8), "X"); 111 | } 112 | 113 | @Override 114 | public void run() { 115 | for (int i = 0; i < this.runs; i++) { 116 | this.logger.info(fmt, i, i * 7L, i / 16.0); 117 | } 118 | } 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /logger-slf4j-2/src/test/resources/chronicle.logger.perf.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2014-2017 Chronicle Software 3 | # 4 | # https://chronicle.software 5 | # 6 | # This program is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License 16 | # along with this program. If not, see . 17 | # 18 | 19 | chronicle.logger.base = ${java.io.tmpdir}/chronicle-slf4j 20 | 21 | chronicle.logger.root.path = ${chronicle.logger.base}/perf 22 | chronicle.logger.root.level = debug 23 | chronicle.logger.root.append = false 24 | -------------------------------------------------------------------------------- /logger-slf4j-2/src/test/resources/chronicle.logger.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2014-2017 Chronicle Software 3 | # 4 | # https://chronicle.software 5 | # 6 | # This program is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License 16 | # along with this program. If not, see . 17 | # 18 | 19 | ################################################################################ 20 | # Common 21 | ################################################################################ 22 | 23 | chronicle.logger.base = ${java.io.tmpdir}/chronicle-slf4j 24 | chronicle.logger.root.path = ${chronicle.logger.base}/root 25 | chronicle.logger.root.level = debug 26 | chronicle.logger.root.append = false 27 | 28 | ################################################################################ 29 | # Loggers 30 | ################################################################################ 31 | 32 | # logger : Logger1 33 | chronicle.logger.logger_1.path = ${chronicle.logger.base}/logger_1 34 | chronicle.logger.logger_1.level = info 35 | 36 | # logger : impl 37 | chronicle.logger.readwrite.path = ${chronicle.logger.base}/readwrite 38 | -------------------------------------------------------------------------------- /logger-slf4j/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 22 | 23 | 4.0.0 24 | 25 | 26 | net.openhft 27 | chronicle-logger 28 | 4.27ea2-SNAPSHOT 29 | ../pom.xml 30 | 31 | 32 | OpenHFT/Chronicle-Logger/logger-slf4j 33 | chronicle-logger-slf4j 34 | bundle 35 | 36 | 37 | 38 | net.openhft 39 | chronicle-logger-core 40 | 41 | 42 | 43 | 44 | org.slf4j 45 | slf4j-api 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | org.apache.maven.plugins 54 | maven-surefire-plugin 55 | 56 | 57 | **/*PerfTest.java 58 | 59 | 60 | ${project.build.directory} 61 | 62 | 63 | 64 | 72 | 73 | org.apache.servicemix.tooling 74 | depends-maven-plugin 75 | 76 | 77 | generate-depends-file 78 | 79 | generate-depends-file 80 | 81 | 82 | 83 | 84 | 85 | org.apache.felix 86 | maven-bundle-plugin 87 | true 88 | 89 | 90 | ${project.groupId}.${project.artifactId} 91 | OpenHFT :: ${project.artifactId} 92 | ${project.version} 93 | net.openhft.chronicle.logger.slf4j.* 94 | 95 | 96 | 97 | 101 | 102 | 103 | manifest 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 113 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 114 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 115 | master 116 | 117 | 118 | 119 | -------------------------------------------------------------------------------- /logger-slf4j/src/main/java/net/openhft/chronicle/logger/slf4j/ChronicleLoggerFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.slf4j; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogManager; 21 | import net.openhft.chronicle.logger.ChronicleLogWriter; 22 | import org.slf4j.ILoggerFactory; 23 | import org.slf4j.Logger; 24 | import org.slf4j.helpers.NOPLogger; 25 | import org.slf4j.impl.SimpleLogger; 26 | 27 | import java.util.Map; 28 | import java.util.concurrent.ConcurrentHashMap; 29 | 30 | /** 31 | * Simple implementation of Logger that sends all enabled slf4j messages, 32 | * for all defined loggers, to one or more VanillaChronicle.. 33 | * 34 | * To configure this sl4j binding you need to specify the location of a properties 35 | * files via system properties: 36 | * {@code -Dchronicle.logger.properties=${pathOfYourPropertiesFile}} 37 | * 38 | * The following system properties are supported to configure the behavior of this 39 | * logger: 40 | * 41 | * {@code chronicle.logger.root.path} 42 | * {@code chronicle.logger.root.level} 43 | * {@code chronicle.logger.root.append} 44 | * 45 | */ 46 | public class ChronicleLoggerFactory implements ILoggerFactory { 47 | private final Map loggers; 48 | private final ChronicleLogManager manager; 49 | 50 | // ************************************************************************* 51 | // 52 | // ************************************************************************* 53 | 54 | /** 55 | * c-tor 56 | */ 57 | public ChronicleLoggerFactory() { 58 | this.loggers = new ConcurrentHashMap<>(); 59 | this.manager = ChronicleLogManager.getInstance(); 60 | } 61 | 62 | // ************************************************************************* 63 | // for testing 64 | // ************************************************************************* 65 | 66 | /** 67 | * Return an appropriate {@link ChronicleLogger} instance by name. 68 | */ 69 | @Override 70 | public Logger getLogger(String name) { 71 | try { 72 | return doGetLogger(name); 73 | } catch (Exception e) { 74 | System.err.println("Unable to initialize chronicle-logger-slf4j (" + name + ")\n " + e.getMessage()); 75 | e.printStackTrace(); 76 | } 77 | 78 | return NOPLogger.NOP_LOGGER; 79 | } 80 | 81 | // ************************************************************************* 82 | // 83 | // ************************************************************************* 84 | 85 | synchronized void reload() { 86 | this.loggers.clear(); 87 | this.manager.reload(); 88 | } 89 | 90 | private synchronized Logger doGetLogger(String name) { 91 | Logger logger = loggers.get(name); 92 | if (logger == null) { 93 | if (name != null && name.startsWith("net.openhft")) { 94 | SimpleLogger.lazyInit(); 95 | logger = new SimpleLogger(name); 96 | } else { 97 | final ChronicleLogWriter writer = manager.getWriter(name); 98 | logger = new ChronicleLogger(writer, name, manager.cfg().getLevel(name)); 99 | } 100 | loggers.put(name, logger); 101 | } 102 | 103 | return logger; 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /logger-slf4j/src/main/java/net/openhft/chronicle/logger/slf4j/internal/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This package and any and all sub-packages contains strictly internal classes for this Chronicle library. 3 | * Internal classes shall never be used directly. 4 | * 5 | * Specifically, the following actions (including, but not limited to) are not allowed 6 | * on internal classes and packages: 7 | * 8 | * Casting to 9 | * Reflection of any kind 10 | * Explicit Serialize/deserialize 11 | * 12 | * 13 | * The classes in this package and any sub-package are subject to 14 | * changes at any time for any reason. 15 | */ 16 | package net.openhft.chronicle.logger.slf4j.internal; 17 | -------------------------------------------------------------------------------- /logger-slf4j/src/main/java/org/slf4j/impl/OutputChoice.java: -------------------------------------------------------------------------------- 1 | package org.slf4j.impl; 2 | 3 | import java.io.PrintStream; 4 | 5 | /** 6 | * This class encapsulates the user's choice of output target. 7 | * 8 | * @author Ceki Gülcü 9 | * 10 | */ 11 | class OutputChoice { 12 | 13 | enum OutputChoiceType { 14 | SYS_OUT, CACHED_SYS_OUT, SYS_ERR, CACHED_SYS_ERR, FILE; 15 | } 16 | 17 | final OutputChoiceType outputChoiceType; 18 | final PrintStream targetPrintStream; 19 | 20 | OutputChoice(OutputChoiceType outputChoiceType) { 21 | if (outputChoiceType == OutputChoiceType.FILE) { 22 | throw new IllegalArgumentException(); 23 | } 24 | this.outputChoiceType = outputChoiceType; 25 | if (outputChoiceType == OutputChoiceType.CACHED_SYS_OUT) { 26 | this.targetPrintStream = System.out; 27 | } else if (outputChoiceType == OutputChoiceType.CACHED_SYS_ERR) { 28 | this.targetPrintStream = System.err; 29 | } else { 30 | this.targetPrintStream = null; 31 | } 32 | } 33 | 34 | OutputChoice(PrintStream printStream) { 35 | this.outputChoiceType = OutputChoiceType.FILE; 36 | this.targetPrintStream = printStream; 37 | } 38 | 39 | PrintStream getTargetPrintStream() { 40 | switch (outputChoiceType) { 41 | case SYS_OUT: 42 | return System.out; 43 | case SYS_ERR: 44 | return System.err; 45 | case CACHED_SYS_ERR: 46 | case CACHED_SYS_OUT: 47 | case FILE: 48 | return targetPrintStream; 49 | default: 50 | throw new IllegalArgumentException(); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /logger-slf4j/src/main/java/org/slf4j/impl/StaticLoggerBinder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.slf4j.impl; 19 | 20 | import net.openhft.chronicle.logger.slf4j.ChronicleLoggerFactory; 21 | import org.slf4j.ILoggerFactory; 22 | import org.slf4j.spi.LoggerFactoryBinder; 23 | 24 | public class StaticLoggerBinder implements LoggerFactoryBinder { 25 | 26 | private static final StaticLoggerBinder SINGLETON = new StaticLoggerBinder(); 27 | private static final String loggerFactoryClassStr = ChronicleLoggerFactory.class.getName(); 28 | /** 29 | * Declare the version of the SLF4J API this implementation is compiled 30 | * against. The value of this field is usually modified with each release. 31 | */ 32 | // to avoid constant folding by the compiler, this field must *not* be final 33 | public static String REQUESTED_API_VERSION = "1.7.30"; // !final 34 | /** 35 | * The ILoggerFactory instance returned by the {@link #getLoggerFactory} 36 | * method should always be the same object 37 | */ 38 | private final ILoggerFactory loggerFactory; 39 | 40 | /** 41 | * c-tor 42 | */ 43 | private StaticLoggerBinder() { 44 | loggerFactory = new ChronicleLoggerFactory(); 45 | } 46 | 47 | /** 48 | * Return the singleton of this class. 49 | * 50 | * @return the StaticLoggerBinder singleton 51 | */ 52 | public static final StaticLoggerBinder getSingleton() { 53 | return SINGLETON; 54 | } 55 | 56 | @Override 57 | public ILoggerFactory getLoggerFactory() { 58 | return loggerFactory; 59 | } 60 | 61 | @Override 62 | public String getLoggerFactoryClassStr() { 63 | return loggerFactoryClassStr; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /logger-slf4j/src/main/java/org/slf4j/impl/StaticMarkerBinder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.slf4j.impl; 19 | 20 | import org.slf4j.IMarkerFactory; 21 | import org.slf4j.helpers.BasicMarkerFactory; 22 | import org.slf4j.spi.MarkerFactoryBinder; 23 | 24 | /** 25 | * The binding of {@link org.slf4j.MarkerFactory} class with an actual instance of 26 | * {@link IMarkerFactory} is performed using information returned by this class. 27 | * 28 | * @author Ceki Gülcü 29 | */ 30 | public class StaticMarkerBinder implements MarkerFactoryBinder { 31 | 32 | /** 33 | * The unique instance of this class. 34 | */ 35 | public static final StaticMarkerBinder SINGLETON = new StaticMarkerBinder(); 36 | 37 | final IMarkerFactory markerFactory = new BasicMarkerFactory(); 38 | 39 | private StaticMarkerBinder() { 40 | } 41 | 42 | /** 43 | * Currently this method always returns an instance of 44 | * {@link BasicMarkerFactory}. 45 | */ 46 | @Override 47 | public IMarkerFactory getMarkerFactory() { 48 | return markerFactory; 49 | } 50 | 51 | /** 52 | * Currently, this method returns the class name of 53 | * {@link BasicMarkerFactory}. 54 | */ 55 | @Override 56 | public String getMarkerFactoryClassStr() { 57 | return BasicMarkerFactory.class.getName(); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /logger-slf4j/src/test/java/net/openhft/chronicle/logger/slf4j/ChronicleLoggingConfigTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.slf4j; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogConfig; 21 | import org.junit.Test; 22 | 23 | import static org.junit.Assert.assertNotNull; 24 | 25 | public class ChronicleLoggingConfigTest { 26 | @Test 27 | public void testLoadClasspathIndexed() { 28 | System.setProperty("chronicle.logger.properties", "chronicle.logger.properties"); 29 | assertLoadsValidConfig(); 30 | } 31 | 32 | private void assertLoadsValidConfig() { 33 | ChronicleLogConfig config = ChronicleLogConfig.load(); 34 | assertNotNull("unable to load config", config); 35 | assertNotNull("is not a valid config", config.getAppenderConfig()); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /logger-slf4j/src/test/java/net/openhft/chronicle/logger/slf4j/Slf4jChronicleConfigurationTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.slf4j; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogConfig; 21 | import net.openhft.chronicle.logger.ChronicleLogLevel; 22 | import org.junit.Test; 23 | 24 | import java.io.File; 25 | import java.util.Properties; 26 | 27 | import static org.junit.Assert.assertEquals; 28 | import static org.junit.Assert.assertNotNull; 29 | 30 | public class Slf4jChronicleConfigurationTest extends Slf4jTestBase { 31 | 32 | @Test 33 | public void testLoadProperties() { 34 | final String cfgPath = "chronicle.logger.properties"; 35 | final ChronicleLogConfig cfg = ChronicleLogConfig.load(cfgPath); 36 | 37 | assertNotNull(cfg); 38 | 39 | assertEquals( 40 | new File(basePath("root")), 41 | new File(cfg.getString(ChronicleLogConfig.KEY_PATH))); 42 | assertEquals( 43 | ChronicleLogLevel.DEBUG.toString(), 44 | cfg.getString(ChronicleLogConfig.KEY_LEVEL).toUpperCase()); 45 | assertEquals("false", cfg.getString(ChronicleLogConfig.KEY_APPEND)); 46 | assertEquals( 47 | new File(basePath("logger_1")), 48 | new File(cfg.getString("logger_1", ChronicleLogConfig.KEY_PATH))); 49 | assertEquals( 50 | ChronicleLogLevel.INFO.toString(), 51 | cfg.getString("logger_1", ChronicleLogConfig.KEY_LEVEL).toUpperCase()); 52 | assertEquals( 53 | ChronicleLogLevel.DEBUG.toString(), 54 | cfg.getString("readwrite", ChronicleLogConfig.KEY_LEVEL).toUpperCase()); 55 | } 56 | 57 | @Test 58 | public void testLoadConfig() { 59 | final Properties properties = new Properties(); 60 | properties.setProperty("chronicle.logger.root.cfg.blockSize", "256"); 61 | 62 | final ChronicleLogConfig clc = ChronicleLogConfig.load(properties); 63 | assertNotNull(clc.getAppenderConfig()); 64 | 65 | assertEquals(256, clc.getAppenderConfig().getBlockSize()); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /logger-slf4j/src/test/java/net/openhft/chronicle/logger/slf4j/Slf4jChronicleLoggerPerfTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.slf4j; 19 | 20 | import net.openhft.chronicle.core.io.IOTools; 21 | import org.apache.commons.lang3.StringUtils; 22 | import org.junit.After; 23 | import org.junit.Before; 24 | import org.junit.Ignore; 25 | import org.junit.Test; 26 | import org.slf4j.Logger; 27 | import org.slf4j.LoggerFactory; 28 | 29 | import java.util.concurrent.ExecutorService; 30 | import java.util.concurrent.Executors; 31 | import java.util.concurrent.TimeUnit; 32 | 33 | @Ignore 34 | public class Slf4jChronicleLoggerPerfTest extends Slf4jTestBase { 35 | 36 | // ************************************************************************* 37 | // 38 | // ************************************************************************* 39 | 40 | @Before 41 | public void setUp() { 42 | System.setProperty( 43 | "chronicle.logger.properties", 44 | "chronicle.logger.perf.properties"); 45 | 46 | getChronicleLoggerFactory().reload(); 47 | } 48 | 49 | @After 50 | public void tearDown() { 51 | IOTools.deleteDirWithFiles(basePath()); 52 | } 53 | 54 | // ************************************************************************* 55 | // Single Thread 56 | // ************************************************************************* 57 | 58 | @Test 59 | public void testSingleThreadLogging1() { 60 | Thread.currentThread().setName("perf-plain"); 61 | 62 | final String testId = "perf-chronicle"; 63 | final Logger clogger = LoggerFactory.getLogger(testId); 64 | final long items = 1000000; 65 | 66 | warmup(clogger); 67 | 68 | for (int s = 64; s <= 1024; s += 64) { 69 | final String staticStr = StringUtils.leftPad("", s, 'X'); 70 | 71 | long cStart1 = System.nanoTime(); 72 | 73 | for (int i = 1; i <= items; i++) { 74 | clogger.info(staticStr); 75 | } 76 | 77 | long cEnd1 = System.nanoTime(); 78 | 79 | System.out.printf("items=%03d size=%04d => chronology=%.3f ms, chronology-average=%.3f us\n", 80 | items, 81 | staticStr.length(), 82 | (cEnd1 - cStart1) / 1e6, 83 | (cEnd1 - cStart1) / items / 1e3); 84 | } 85 | } 86 | 87 | @Test 88 | public void testSingleThreadLogging2() { 89 | Thread.currentThread().setName("perf-plain"); 90 | 91 | final String testId = "perf-chronicle"; 92 | final Logger clogger = LoggerFactory.getLogger(testId); 93 | final long items = 1000000; 94 | final String strFmt = StringUtils.leftPad("> v1={}, v2={}, v3={}", 32, 'X'); 95 | 96 | warmup(clogger); 97 | 98 | for (int n = 0; n < 10; n++) { 99 | long cStart1 = System.nanoTime(); 100 | 101 | for (int i = 1; i <= items; i++) { 102 | clogger.info(strFmt, i, i * 10, i / 16); 103 | } 104 | 105 | long cEnd1 = System.nanoTime(); 106 | 107 | System.out.printf("items=%03d => chronology=%.3f ms, chronology-average=%.3f us\n", 108 | items, 109 | (cEnd1 - cStart1) / 1e6, 110 | (cEnd1 - cStart1) / items / 1e3); 111 | } 112 | } 113 | 114 | // ************************************************************************* 115 | // Multi Thread 116 | // ************************************************************************* 117 | 118 | @Test 119 | public void testMultiThreadLogging() throws InterruptedException { 120 | warmup(LoggerFactory.getLogger("perf-chronicle")); 121 | 122 | final int RUNS = 1000000; 123 | final int THREADS = 10; 124 | 125 | for (int size : new int[]{64, 128, 256}) { 126 | { 127 | final long start = System.nanoTime(); 128 | 129 | ExecutorService es = Executors.newFixedThreadPool(THREADS); 130 | for (int t = 0; t < THREADS; t++) { 131 | es.submit(new RunnableLogger(RUNS, size, "perf-chronicle")); 132 | } 133 | 134 | es.shutdown(); 135 | es.awaitTermination(5, TimeUnit.SECONDS); 136 | 137 | final long time = System.nanoTime() - start; 138 | 139 | System.out.printf("ChronicleLog.MT (runs=%d, min size=%03d, elapsed=%.3f ms) took an average of %.3f us per entry\n", 140 | RUNS, 141 | size, 142 | time / 1e6, 143 | time / 1e3 / (RUNS * THREADS) 144 | ); 145 | } 146 | } 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /logger-slf4j/src/test/java/net/openhft/chronicle/logger/slf4j/Slf4jTestBase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.slf4j; 19 | 20 | import net.openhft.chronicle.core.OS; 21 | import net.openhft.chronicle.core.util.Time; 22 | import net.openhft.chronicle.logger.ChronicleLogLevel; 23 | import org.apache.commons.lang3.StringUtils; 24 | import org.slf4j.Logger; 25 | import org.slf4j.LoggerFactory; 26 | import org.slf4j.impl.StaticLoggerBinder; 27 | 28 | class Slf4jTestBase { 29 | 30 | // ************************************************************************* 31 | // 32 | // ************************************************************************* 33 | 34 | static final ChronicleLogLevel[] LOG_LEVELS = ChronicleLogLevel.values(); 35 | 36 | static String basePath() { 37 | String path = System.getProperty("java.io.tmpdir"); 38 | String sep = System.getProperty("file.separator"); 39 | 40 | if (!path.endsWith(sep)) { 41 | path += sep; 42 | } 43 | 44 | return path + "chronicle-slf4j"; 45 | } 46 | 47 | static String basePath(String loggerName) { 48 | return basePath() 49 | + System.getProperty("file.separator") 50 | + loggerName; 51 | } 52 | 53 | static void log(Logger logger, ChronicleLogLevel level, String fmt, Object... args) { 54 | switch (level) { 55 | case TRACE: 56 | logger.trace(fmt, args); 57 | break; 58 | 59 | case DEBUG: 60 | logger.debug(fmt, args); 61 | break; 62 | 63 | case INFO: 64 | logger.info(fmt, args); 65 | break; 66 | 67 | case WARN: 68 | logger.warn(fmt, args); 69 | break; 70 | 71 | case ERROR: 72 | logger.error(fmt, args); 73 | break; 74 | default: 75 | throw new UnsupportedOperationException(); 76 | } 77 | } 78 | 79 | static void warmup(Logger logger) { 80 | for (int i = 0; i < 10; i++) { 81 | logger.info("warmup"); 82 | } 83 | } 84 | 85 | // ************************************************************************* 86 | // 87 | // ************************************************************************* 88 | 89 | /** 90 | * @return the ChronicleLoggerFactory singleton 91 | */ 92 | ChronicleLoggerFactory getChronicleLoggerFactory() { 93 | return (ChronicleLoggerFactory) StaticLoggerBinder.getSingleton().getLoggerFactory(); 94 | } 95 | 96 | // ************************************************************************* 97 | // 98 | // ************************************************************************* 99 | 100 | protected final class RunnableLogger implements Runnable { 101 | private final Logger logger; 102 | private final int runs; 103 | private final String fmt; 104 | private final String fmtBase = " > val1={}, val2={}, val3={}"; 105 | 106 | public RunnableLogger(int runs, int pad, String loggerName) { 107 | this.logger = LoggerFactory.getLogger(loggerName); 108 | this.runs = runs; 109 | this.fmt = StringUtils.rightPad(fmtBase, pad + fmtBase.length() - (4 + 8 + 8), "X"); 110 | } 111 | 112 | @Override 113 | public void run() { 114 | for (int i = 0; i < this.runs; i++) { 115 | this.logger.info(fmt, i, i * 7L, i / 16.0); 116 | } 117 | } 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /logger-slf4j/src/test/resources/chronicle.logger.perf.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2014-2017 Chronicle Software 3 | # 4 | # https://chronicle.software 5 | # 6 | # This program is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License 16 | # along with this program. If not, see . 17 | # 18 | 19 | chronicle.logger.base = ${java.io.tmpdir}/chronicle-slf4j 20 | 21 | chronicle.logger.root.path = ${chronicle.logger.base}/perf 22 | chronicle.logger.root.level = debug 23 | chronicle.logger.root.append = false 24 | -------------------------------------------------------------------------------- /logger-slf4j/src/test/resources/chronicle.logger.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2014-2017 Chronicle Software 3 | # 4 | # https://chronicle.software 5 | # 6 | # This program is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License 16 | # along with this program. If not, see . 17 | # 18 | 19 | ################################################################################ 20 | # Common 21 | ################################################################################ 22 | 23 | chronicle.logger.base = ${java.io.tmpdir}/chronicle-slf4j 24 | chronicle.logger.root.path = ${chronicle.logger.base}/root 25 | chronicle.logger.root.level = debug 26 | chronicle.logger.root.append = false 27 | 28 | ################################################################################ 29 | # Loggers 30 | ################################################################################ 31 | 32 | # logger : Logger1 33 | chronicle.logger.logger_1.path = ${chronicle.logger.base}/logger_1 34 | chronicle.logger.logger_1.level = info 35 | 36 | # logger : impl 37 | chronicle.logger.readwrite.path = ${chronicle.logger.base}/readwrite 38 | -------------------------------------------------------------------------------- /logger-tools/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 22 | 23 | 4.0.0 24 | 25 | 26 | net.openhft 27 | chronicle-logger 28 | 4.27ea2-SNAPSHOT 29 | ../pom.xml 30 | 31 | 32 | OpenHFT/Chronicle-Logger/logger-tools 33 | chronicle-logger-tools 34 | bundle 35 | 36 | 37 | 38 | net.openhft 39 | chronicle-logger-core 40 | 41 | 42 | 43 | net.openhft 44 | chronicle-wire 45 | 46 | 47 | 48 | 49 | org.slf4j 50 | slf4j-api 51 | 52 | 53 | 54 | 55 | net.openhft 56 | chronicle-logger-logback 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | org.apache.maven.plugins 65 | maven-surefire-plugin 66 | 67 | 1 68 | false 69 | 70 | **/*PerfTest.java 71 | 72 | 73 | ${project.build.directory} 74 | 75 | 76 | 77 | 85 | 86 | org.apache.servicemix.tooling 87 | depends-maven-plugin 88 | 89 | 90 | generate-depends-file 91 | 92 | generate-depends-file 93 | 94 | 95 | 96 | 97 | 98 | org.apache.felix 99 | maven-bundle-plugin 100 | true 101 | 102 | 103 | ${project.groupId}.${project.artifactId} 104 | OpenHFT :: ${project.artifactId} 105 | ${project.version} 106 | net.openhft.chronicle.logger.tools.* 107 | 108 | 109 | 110 | 114 | 115 | 116 | manifest 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 126 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 127 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 128 | master 129 | 130 | 131 | 132 | -------------------------------------------------------------------------------- /logger-tools/src/main/java/net/openhft/chronicle/logger/tools/ChroniCat.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.tools; 19 | 20 | import net.openhft.chronicle.wire.WireType; 21 | 22 | public final class ChroniCat { 23 | 24 | private ChroniCat() { 25 | } 26 | 27 | public static void main(String[] args) { 28 | try { 29 | 30 | if (args.length >= 1) { 31 | int i = 0; 32 | final WireType wt; 33 | if ("-w".equals(args[i])) { 34 | wt = WireType.valueOf(args[++i].trim().toUpperCase()); 35 | i++; 36 | } else { 37 | wt = WireType.BINARY_LIGHT; 38 | } 39 | 40 | ChronicleLogReader reader = new ChronicleLogReader(args[i].trim(), wt); 41 | 42 | reader.processLogs(ChronicleLogReader::printf, false); 43 | 44 | } else { 45 | System.err.println("\nUsage: ChroniCat [-w ] "); 46 | System.err.println(" - wire format, default BINARY_LIGHT"); 47 | System.err.println(" - base path of Chronicle Logs storage"); 48 | } 49 | } catch (Exception e) { 50 | e.printStackTrace(System.err); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /logger-tools/src/main/java/net/openhft/chronicle/logger/tools/ChroniTail.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.tools; 19 | 20 | import net.openhft.chronicle.wire.WireType; 21 | 22 | public final class ChroniTail { 23 | 24 | private ChroniTail() { 25 | } 26 | 27 | public static void main(String[] args) { 28 | try { 29 | 30 | if (args.length >= 1) { 31 | int i = 0; 32 | final WireType wt; 33 | if ("-w".equals(args[i++])) { 34 | wt = WireType.valueOf(args[i++].trim().toUpperCase()); 35 | } else { 36 | wt = WireType.BINARY_LIGHT; 37 | } 38 | 39 | ChronicleLogReader reader = new ChronicleLogReader(args[i].trim(), wt); 40 | 41 | reader.processLogs(ChronicleLogReader::printf, true); 42 | 43 | } else { 44 | System.err.println("\nUsage: ChroniTail [-w ] "); 45 | System.err.println(" - wire format, default BINARY_LIGHT"); 46 | System.err.println(" - base path of Chronicle Logs storage"); 47 | } 48 | } catch (Exception e) { 49 | e.printStackTrace(System.err); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /logger-tools/src/main/java/net/openhft/chronicle/logger/tools/ChronicleLogProcessor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.tools; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogLevel; 21 | import org.jetbrains.annotations.Nullable; 22 | 23 | public interface ChronicleLogProcessor { 24 | void process( 25 | final long timestamp, 26 | final ChronicleLogLevel level, 27 | final String loggerName, 28 | final String threadName, 29 | final String message, 30 | @Nullable final Throwable throwable, 31 | final Object[] args); 32 | } 33 | -------------------------------------------------------------------------------- /logger-tools/src/main/java/net/openhft/chronicle/logger/tools/ChronicleLogReader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2022 Chronicle Software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.tools; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogLevel; 21 | import net.openhft.chronicle.queue.ChronicleQueue; 22 | import net.openhft.chronicle.queue.ExcerptTailer; 23 | import net.openhft.chronicle.wire.DocumentContext; 24 | import net.openhft.chronicle.wire.Wire; 25 | import net.openhft.chronicle.wire.WireType; 26 | import org.jetbrains.annotations.NotNull; 27 | import org.jetbrains.annotations.Nullable; 28 | import org.slf4j.helpers.MessageFormatter; 29 | 30 | import java.text.SimpleDateFormat; 31 | import java.util.ArrayList; 32 | import java.util.List; 33 | 34 | /** 35 | * Generic tool allowing users to process Chronicle logs in their own way 36 | */ 37 | public class ChronicleLogReader { 38 | private static final SimpleDateFormat tsFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); 39 | private final ChronicleQueue cq; 40 | 41 | /** 42 | * Create reader with default wire type 43 | * 44 | * @param path the path to Chronicle Logs storage 45 | */ 46 | public ChronicleLogReader( 47 | @NotNull String path) { 48 | this(path, WireType.BINARY_LIGHT); 49 | } 50 | 51 | /** 52 | * @param path the path to Chronicle Logs storage 53 | * @param wireType Chronicle wire type. Must match the wire type specified in corresponding Chronicle Logger 54 | */ 55 | public ChronicleLogReader( 56 | @NotNull String path, 57 | @NotNull WireType wireType) { 58 | cq = ChronicleQueue.singleBuilder(path).wireType(wireType).build(); 59 | } 60 | 61 | /** 62 | * Simple {@link ChronicleLogProcessor} implementation. Prints formatted message to stdout 63 | */ 64 | public static void printf( 65 | long timestamp, 66 | ChronicleLogLevel level, 67 | String loggerName, 68 | String threadName, 69 | String message, 70 | @Nullable Throwable throwable, 71 | Object[] args) { 72 | 73 | message = MessageFormatter.arrayFormat(message, args).getMessage(); 74 | 75 | if (throwable == null) { 76 | System.out.printf("%s [%s] [%s] [%s] %s%n", 77 | tsFormat.format(timestamp), 78 | level.toString(), 79 | threadName, 80 | loggerName, 81 | message); 82 | 83 | } else { 84 | System.out.printf("%s [%s] [%s] [%s] %s%n%s%n", 85 | tsFormat.format(timestamp), 86 | level.toString(), 87 | threadName, 88 | loggerName, 89 | message, 90 | throwable.toString()); 91 | } 92 | } 93 | 94 | /** 95 | * Decode logs 96 | * 97 | * @param processor user-provided processor called for each log message 98 | * @param waitForIt whether to wait for more data or stop after EOF reached 99 | */ 100 | public void processLogs(@NotNull ChronicleLogProcessor processor, boolean waitForIt) { 101 | ExcerptTailer tailer = cq.createTailer(); 102 | for (; ; ) { 103 | try (DocumentContext dc = tailer.readingDocument()) { 104 | Wire wire = dc.wire(); 105 | if (wire == null) 106 | if (waitForIt) { 107 | try { 108 | Thread.sleep(50L); 109 | } catch (InterruptedException ignored) { 110 | 111 | } 112 | continue; 113 | } else { 114 | break; 115 | } 116 | 117 | long timestamp = wire.read("ts").int64(); 118 | ChronicleLogLevel level = wire.read("level").asEnum(ChronicleLogLevel.class); 119 | String threadName = wire.read("threadName").text(); 120 | String loggerName = wire.read("loggerName").text(); 121 | String message = wire.read("message").text(); 122 | Throwable th = wire.hasMore() ? wire.read("throwable").throwable(false) : null; 123 | List argsL = new ArrayList<>(); 124 | if (wire.hasMore()) { 125 | wire.read("args").sequence(argsL, (l, vi) -> { 126 | while (vi.hasNextSequenceItem()) { 127 | l.add(vi.object(Object.class)); 128 | } 129 | }); 130 | } 131 | Object[] args = argsL.toArray(new Object[argsL.size()]); 132 | processor.process(timestamp, level, threadName, loggerName, message, th, args); 133 | } 134 | } 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /logger-tools/src/main/java/net/openhft/chronicle/logger/tools/internal/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This package and any and all sub-packages contains strictly internal classes for this Chronicle library. 3 | * Internal classes shall never be used directly. 4 | * 5 | * Specifically, the following actions (including, but not limited to) are not allowed 6 | * on internal classes and packages: 7 | * 8 | * Casting to 9 | * Reflection of any kind 10 | * Explicit Serialize/deserialize 11 | * 12 | * 13 | * The classes in this package and any sub-package are subject to 14 | * changes at any time for any reason. 15 | */ 16 | package net.openhft.chronicle.logger.tools.internal; 17 | -------------------------------------------------------------------------------- /logger-tools/src/test/java/net/openhft/chronicle/logger/tools/ChronicleLogReaderTest.java: -------------------------------------------------------------------------------- 1 | package net.openhft.chronicle.logger.tools; 2 | 3 | import net.openhft.chronicle.core.OS; 4 | import net.openhft.chronicle.core.util.Time; 5 | import net.openhft.chronicle.wire.WireType; 6 | import org.junit.Before; 7 | import org.junit.Test; 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | 11 | public class ChronicleLogReaderTest { 12 | @Before 13 | public void setup() { 14 | System.setProperty( 15 | "logback.configurationFile", 16 | System.getProperty("resources.path") 17 | + "/logback-chronicle-binary-appender.xml"); 18 | } 19 | 20 | @Test 21 | public void readTest() { 22 | final Logger logger = LoggerFactory.getLogger("binary-chronicle"); 23 | logger.info("test {} {} {}", 1, 100L, 100.123D); 24 | logger.info("test {} {} {}", 2, 100L, 100.123D); 25 | logger.info("test {} {} {}", 3, 100L, 100.123D); 26 | 27 | ChronicleLogReader reader = new ChronicleLogReader(OS.getTarget() + "/chronicle-logback/binary-chronicle" + Time.uniqueId(), WireType.BINARY_LIGHT); 28 | reader.processLogs(ChronicleLogReader::printf, false); 29 | 30 | //ChroniCat.main(new String[] {OS.getTarget() + "/chronicle-logback/binary-chronicle"}); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /logger-tools/src/test/resources/logback-chronicle-binary-appender.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 22 | 23 | 25 | 26 | %d %contextName [%t] %level %logger{36} - %msg%n 27 | 28 | 29 | 31 | ${java.io.tmpdir}/chronicle-logback/binary-chronicle 32 | false 33 | false 34 | 35 | 128 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 4.0.0 22 | 23 | 24 | net.openhft 25 | java-parent-pom 26 | 1.27ea1 27 | 28 | 29 | 30 | chronicle-logger 31 | 4.27ea2-SNAPSHOT 32 | pom 33 | 34 | OpenHFT/Chronicle-Logger 35 | OpenHFT :: High Performance Logging 36 | 37 | 38 | 39 | 40 | net.openhft 41 | third-party-bom 42 | 3.27ea2 43 | pom 44 | import 45 | 46 | 47 | 48 | net.openhft 49 | chronicle-bom 50 | 2.27ea-SNAPSHOT 51 | pom 52 | import 53 | 54 | 55 | 56 | 57 | net.openhft 58 | chronicle-logger-core 59 | ${project.version} 60 | 61 | 62 | 63 | net.openhft 64 | chronicle-logger-logback 65 | ${project.version} 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | net.openhft 75 | chronicle-core 76 | 77 | 78 | 79 | net.openhft 80 | chronicle-bytes 81 | 82 | 83 | 84 | net.openhft 85 | chronicle-queue 86 | 87 | 88 | 89 | org.jetbrains 90 | annotations 91 | 92 | 93 | 94 | 95 | org.apache.commons 96 | commons-lang3 97 | test 98 | 99 | 100 | junit 101 | junit 102 | test 103 | 104 | 105 | 106 | 107 | org.openjdk.jmh 108 | jmh-core 109 | test 110 | 111 | 112 | org.openjdk.jmh 113 | jmh-core-benchmarks 114 | test 115 | 116 | 117 | 118 | 119 | logger-core 120 | logger-jul 121 | logger-jcl 122 | logger-slf4j 123 | logger-slf4j-2 124 | logger-logback 125 | logger-log4j-1 126 | logger-log4j-2 127 | logger-tools 128 | benchmark 129 | 130 | 131 | 132 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 133 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 134 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 135 | master 136 | 137 | 138 | 139 | 140 | --------------------------------------------------------------------------------
13 | * The classes in this package and any sub-package are subject to 14 | * changes at any time for any reason. 15 | */ 16 | package net.openhft.chronicle.logger.jcl.internal; 17 | -------------------------------------------------------------------------------- /logger-jcl/src/main/resources/META-INF/services/org.apache.commons.logging.LogFactory: -------------------------------------------------------------------------------- 1 | net.openhft.chronicle.logger.jcl.ChronicleLoggerFactory -------------------------------------------------------------------------------- /logger-jcl/src/test/java/net/openhft/chronicle/logger/jcl/JclTestBase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.jcl; 19 | 20 | import net.openhft.chronicle.core.OS; 21 | import net.openhft.chronicle.core.util.Time; 22 | import net.openhft.chronicle.logger.ChronicleLogLevel; 23 | import org.apache.commons.logging.Log; 24 | 25 | class JclTestBase { 26 | 27 | // ************************************************************************* 28 | // 29 | // ************************************************************************* 30 | 31 | static final ChronicleLogLevel[] LOG_LEVELS = ChronicleLogLevel.values(); 32 | 33 | static String basePath() { 34 | String path = System.getProperty("java.io.tmpdir"); 35 | String sep = System.getProperty("file.separator"); 36 | 37 | if (!path.endsWith(sep)) { 38 | path += sep; 39 | } 40 | 41 | return path + "chronicle-jcl"; 42 | } 43 | 44 | static String basePath(String loggerName) { 45 | return basePath() + System.getProperty("file.separator") + loggerName; 46 | } 47 | 48 | static void log(Log logger, ChronicleLogLevel level, String message) { 49 | switch (level) { 50 | case TRACE: 51 | logger.trace(message); 52 | break; 53 | 54 | case DEBUG: 55 | logger.debug(message); 56 | break; 57 | 58 | case INFO: 59 | logger.info(message); 60 | break; 61 | 62 | case WARN: 63 | logger.warn(message); 64 | break; 65 | 66 | case ERROR: 67 | logger.error(message); 68 | break; 69 | default: 70 | throw new UnsupportedOperationException(); 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /logger-jcl/src/test/resources/chronicle.logger.properties: -------------------------------------------------------------------------------- 1 | 2 | # 3 | # Copyright (C) 2014-2017 Chronicle Software 4 | # 5 | # https://chronicle.software 6 | # 7 | # This program is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU Lesser General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License. 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 14 | # GNU 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, see . 18 | # 19 | 20 | ################################################################################ 21 | # Common 22 | ################################################################################ 23 | 24 | chronicle.logger.base = ${java.io.tmpdir}/chronicle-jcl 25 | chronicle.logger.root.path = ${chronicle.logger.base}/root 26 | chronicle.logger.root.level = debug 27 | chronicle.logger.root.append = false 28 | 29 | ################################################################################ 30 | # Loggers 31 | ################################################################################ 32 | 33 | # logger : Logger1 34 | chronicle.logger.logger_1.path = ${chronicle.logger.base}/logger_1 35 | chronicle.logger.logger_1.level = info 36 | chronicle.logger.logger_1.wireType = JSON 37 | 38 | # logger : impl 39 | chronicle.logger.readwrite.path = ${chronicle.logger.base}/readwrite 40 | -------------------------------------------------------------------------------- /logger-jul/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 22 | 23 | 4.0.0 24 | 25 | 26 | net.openhft 27 | chronicle-logger 28 | 4.27ea2-SNAPSHOT 29 | ../pom.xml 30 | 31 | 32 | OpenHFT/Chronicle-Logger/logger-jul 33 | chronicle-logger-jul 34 | bundle 35 | 36 | 37 | 38 | net.openhft 39 | chronicle-logger-core 40 | 41 | 42 | org.slf4j 43 | slf4j-nop 44 | test 45 | 46 | 47 | 48 | 49 | 50 | 51 | org.apache.maven.plugins 52 | maven-surefire-plugin 53 | 54 | 1 55 | false 56 | 57 | **/*PerfTest.java 58 | 59 | 60 | ${project.build.directory} 61 | 62 | ${project.basedir}/src/test/resources 63 | 64 | 65 | 66 | 67 | 75 | 76 | org.apache.servicemix.tooling 77 | depends-maven-plugin 78 | 79 | 80 | generate-depends-file 81 | 82 | generate-depends-file 83 | 84 | 85 | 86 | 87 | 88 | org.apache.felix 89 | maven-bundle-plugin 90 | true 91 | 92 | 93 | ${project.groupId}.${project.artifactId} 94 | OpenHFT :: ${project.artifactId} 95 | ${project.version} 96 | net.openhft.chronicle.logger.jul.* 97 | 98 | 99 | 100 | 104 | 105 | 106 | manifest 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 115 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 116 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 117 | master 118 | 119 | 120 | -------------------------------------------------------------------------------- /logger-jul/src/main/java/net/openhft/chronicle/logger/jul/AbstractChronicleHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.jul; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogWriter; 21 | 22 | import java.io.IOException; 23 | import java.util.logging.Filter; 24 | import java.util.logging.Handler; 25 | import java.util.logging.Level; 26 | import java.util.logging.LogRecord; 27 | 28 | abstract class AbstractChronicleHandler extends Handler { 29 | 30 | private String path; 31 | private ChronicleLogWriter writer; 32 | 33 | protected AbstractChronicleHandler() { 34 | this.path = null; 35 | this.writer = null; 36 | } 37 | 38 | @Override 39 | public void flush() { 40 | } 41 | 42 | @Override 43 | public void close() throws SecurityException { 44 | if (this.writer != null) { 45 | try { 46 | this.writer.close(); 47 | } catch (IOException e) { 48 | // Ignore 49 | } 50 | } 51 | } 52 | 53 | @Override 54 | public void publish(final LogRecord record) { 55 | if ((writer != null) && isLoggable(record)) { 56 | doPublish(record, this.writer); 57 | } 58 | } 59 | 60 | // ************************************************************************* 61 | // 62 | // ************************************************************************* 63 | 64 | protected abstract void doPublish(final LogRecord record, final ChronicleLogWriter writer); 65 | 66 | protected final void setWriter(ChronicleLogWriter appender) { 67 | this.writer = appender; 68 | } 69 | 70 | @Override 71 | public final void setFilter(Filter newFilter) { 72 | super.setFilter(newFilter); 73 | } 74 | 75 | @Override 76 | public final synchronized void setLevel(Level newLevel) { 77 | super.setLevel(newLevel); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /logger-jul/src/main/java/net/openhft/chronicle/logger/jul/ChronicleHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.jul; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogWriter; 21 | import net.openhft.chronicle.logger.DefaultChronicleLogWriter; 22 | import net.openhft.chronicle.logger.LogAppenderConfig; 23 | 24 | import java.io.IOException; 25 | import java.util.logging.Level; 26 | import java.util.logging.LogRecord; 27 | 28 | import static net.openhft.chronicle.logger.ChronicleLogConfig.KEY_WIRETYPE; 29 | 30 | public class ChronicleHandler extends AbstractChronicleHandler { 31 | 32 | @SuppressWarnings("this-escape") 33 | public ChronicleHandler() throws IOException { 34 | ChronicleHandlerConfig handlerCfg = new ChronicleHandlerConfig(getClass()); 35 | String appenderPath = handlerCfg.getString("path", null); 36 | LogAppenderConfig appenderCfg = handlerCfg.getAppenderConfig(); 37 | 38 | setLevel(handlerCfg.getLevel("level", Level.ALL)); 39 | setFilter(handlerCfg.getFilter("filter", null)); 40 | 41 | setWriter(new DefaultChronicleLogWriter(appenderCfg.build( 42 | appenderPath, 43 | handlerCfg.getStringProperty(KEY_WIRETYPE, "BINARY_LIGHT")) 44 | )); 45 | } 46 | 47 | @SuppressWarnings("deprecation") 48 | @Override 49 | protected void doPublish(final LogRecord record, final ChronicleLogWriter writer) { 50 | writer.write( 51 | ChronicleHelper.getLogLevel(record), 52 | record.getMillis(), 53 | "thread-" + record.getThreadID(), 54 | record.getLoggerName(), 55 | record.getMessage(), 56 | record.getThrown(), 57 | record.getParameters()); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /logger-jul/src/main/java/net/openhft/chronicle/logger/jul/ChronicleHelper.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.jul; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogLevel; 21 | 22 | import java.util.HashMap; 23 | import java.util.Map; 24 | import java.util.logging.Level; 25 | import java.util.logging.LogRecord; 26 | 27 | class ChronicleHelper { 28 | 29 | private static final Map julToCHronicleLevelMap; 30 | private static final Map chronicleToJulLevelMap; 31 | 32 | static { 33 | julToCHronicleLevelMap = new HashMap<>(); 34 | julToCHronicleLevelMap.put(Level.ALL, ChronicleLogLevel.TRACE); 35 | julToCHronicleLevelMap.put(Level.FINEST, ChronicleLogLevel.TRACE); 36 | julToCHronicleLevelMap.put(Level.FINER, ChronicleLogLevel.TRACE); 37 | julToCHronicleLevelMap.put(Level.FINE, ChronicleLogLevel.DEBUG); 38 | julToCHronicleLevelMap.put(Level.CONFIG, ChronicleLogLevel.DEBUG); 39 | julToCHronicleLevelMap.put(Level.INFO, ChronicleLogLevel.INFO); 40 | julToCHronicleLevelMap.put(Level.WARNING, ChronicleLogLevel.WARN); 41 | julToCHronicleLevelMap.put(Level.SEVERE, ChronicleLogLevel.ERROR); 42 | 43 | chronicleToJulLevelMap = new HashMap<>(); 44 | chronicleToJulLevelMap.put(ChronicleLogLevel.TRACE, Level.FINER); 45 | chronicleToJulLevelMap.put(ChronicleLogLevel.DEBUG, Level.FINE); 46 | chronicleToJulLevelMap.put(ChronicleLogLevel.INFO, Level.INFO); 47 | chronicleToJulLevelMap.put(ChronicleLogLevel.WARN, Level.WARNING); 48 | chronicleToJulLevelMap.put(ChronicleLogLevel.ERROR, Level.SEVERE); 49 | } 50 | 51 | private ChronicleHelper() { 52 | 53 | } 54 | 55 | static ChronicleLogLevel getLogLevel(final LogRecord julRecord) { 56 | return getLogLevel(julRecord.getLevel()); 57 | } 58 | 59 | static ChronicleLogLevel getLogLevel(final Level julLevel) { 60 | ChronicleLogLevel level = julToCHronicleLevelMap.get(julLevel); 61 | return level != null ? level : ChronicleLogLevel.DEBUG; 62 | } 63 | 64 | static Level getLogLevel(final ChronicleLogLevel chronicleLevel) { 65 | Level level = chronicleToJulLevelMap.get(chronicleLevel); 66 | return level != null ? level : Level.FINE; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /logger-jul/src/main/java/net/openhft/chronicle/logger/jul/ChronicleLoggerManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.jul; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogManager; 21 | import net.openhft.chronicle.logger.ChronicleLogWriter; 22 | 23 | import java.io.IOException; 24 | import java.util.Collections; 25 | import java.util.Enumeration; 26 | import java.util.Map; 27 | import java.util.concurrent.ConcurrentHashMap; 28 | import java.util.logging.LogManager; 29 | import java.util.logging.Logger; 30 | 31 | public class ChronicleLoggerManager extends LogManager { 32 | 33 | private final Map loggers; 34 | private final ChronicleLogManager manager; 35 | 36 | public ChronicleLoggerManager() { 37 | this.loggers = new ConcurrentHashMap<>(); 38 | this.manager = ChronicleLogManager.getInstance(); 39 | } 40 | 41 | @Override 42 | public boolean addLogger(final Logger logger) { 43 | return false; 44 | } 45 | 46 | @Override 47 | public Logger getLogger(final String name) { 48 | try { 49 | return doGetLogger(name); 50 | } catch (Exception e) { 51 | System.err.println("Unable to initialize chronicle-logger-jul (" + name + ")\n " + e.getMessage()); 52 | } 53 | 54 | return ChronicleLogger.Null.INSTANCE; 55 | } 56 | 57 | @Override 58 | public Enumeration getLoggerNames() { 59 | return Collections.enumeration(this.loggers.keySet()); 60 | } 61 | 62 | @Override 63 | public void reset() throws SecurityException { 64 | this.loggers.clear(); 65 | this.manager.clear(); 66 | } 67 | 68 | // ************************************************************************* 69 | // 70 | // ************************************************************************* 71 | 72 | private synchronized Logger doGetLogger(String name) throws IOException { 73 | Logger logger = loggers.get(name); 74 | if (logger == null) { 75 | final ChronicleLogWriter writer = manager.getWriter(name); 76 | logger = new ChronicleLogger( 77 | writer, 78 | name, 79 | manager.cfg().getLevel(name)); 80 | loggers.put(name, logger); 81 | } 82 | 83 | return logger; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /logger-jul/src/main/java/net/openhft/chronicle/logger/jul/internal/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This package and any and all sub-packages contains strictly internal classes for this Chronicle library. 3 | * Internal classes shall never be used directly. 4 | * 5 | * Specifically, the following actions (including, but not limited to) are not allowed 6 | * on internal classes and packages: 7 | * 8 | * Casting to 9 | * Reflection of any kind 10 | * Explicit Serialize/deserialize 11 | * 12 | * 13 | * The classes in this package and any sub-package are subject to 14 | * changes at any time for any reason. 15 | */ 16 | package net.openhft.chronicle.logger.jul.internal; 17 | -------------------------------------------------------------------------------- /logger-jul/src/test/java/net/openhft/chronicle/logger/jul/JulHandlerTestBase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.jul; 19 | 20 | import net.openhft.chronicle.core.OS; 21 | import net.openhft.chronicle.core.util.Time; 22 | 23 | import java.io.File; 24 | import java.io.FileInputStream; 25 | import java.io.IOException; 26 | import java.util.logging.LogManager; 27 | 28 | import static org.junit.Assert.assertNotNull; 29 | import static org.junit.Assert.assertTrue; 30 | 31 | public class JulHandlerTestBase extends JulTestBase { 32 | 33 | // ************************************************************************* 34 | // 35 | // ************************************************************************* 36 | 37 | protected static String rootPath() { 38 | String path = System.getProperty("java.io.tmpdir"); 39 | String sep = System.getProperty("file.separator"); 40 | 41 | if (!path.endsWith(sep)) { 42 | path += sep; 43 | } 44 | 45 | return path + "chronicle-jul"; 46 | } 47 | 48 | protected static String basePath(String type) { 49 | return rootPath() 50 | + System.getProperty("file.separator") 51 | + type; 52 | } 53 | 54 | /** 55 | * @param id the id of the logger 56 | * @throws IOException if an I/O error occurs 57 | */ 58 | protected void setupLogManager(String id) throws IOException { 59 | String cfgPath = System.getProperty("resources.path"); 60 | File cfgFile = new File(cfgPath, id + ".properties"); 61 | 62 | assertNotNull(cfgPath); 63 | assertTrue(cfgFile.exists()); 64 | 65 | LogManager manager = LogManager.getLogManager(); 66 | manager.reset(); 67 | manager.readConfiguration(new FileInputStream(cfgFile)); 68 | } 69 | 70 | // ************************************************************************* 71 | // 72 | // ************************************************************************* 73 | 74 | } 75 | -------------------------------------------------------------------------------- /logger-jul/src/test/java/net/openhft/chronicle/logger/jul/JulLoggerTestBase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.jul; 19 | 20 | import net.openhft.chronicle.core.OS; 21 | import net.openhft.chronicle.core.util.Time; 22 | 23 | import java.util.logging.LogManager; 24 | 25 | class JulLoggerTestBase extends JulTestBase { 26 | 27 | // ************************************************************************* 28 | // 29 | // ************************************************************************* 30 | 31 | static String basePath() { 32 | String path = System.getProperty("java.io.tmpdir"); 33 | String sep = System.getProperty("file.separator"); 34 | 35 | if (!path.endsWith(sep)) { 36 | path += sep; 37 | } 38 | 39 | return path + "chronicle-jul-api"; 40 | } 41 | 42 | static String basePath(String loggerName) { 43 | return basePath() 44 | + System.getProperty("file.separator") 45 | + loggerName; 46 | } 47 | 48 | // ************************************************************************* 49 | // 50 | // ************************************************************************* 51 | 52 | static void setupLogger(Class> testName) { 53 | setupLogger(testName.getSimpleName()); 54 | } 55 | 56 | static void setupLogger(String id) { 57 | System.setProperty( 58 | "java.util.logging.manager", 59 | ChronicleLoggerManager.class.getName()); 60 | System.setProperty( 61 | "sun.util.logging.disableCallerCheck", 62 | "false"); 63 | System.setProperty( 64 | "chronicle.logger.properties", 65 | id.endsWith(".properties") ? id : id + ".properties"); 66 | 67 | LogManager.getLogManager().reset(); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /logger-jul/src/test/java/net/openhft/chronicle/logger/jul/JulTestBase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.jul; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogLevel; 21 | 22 | import java.util.logging.Level; 23 | import java.util.logging.Logger; 24 | 25 | public class JulTestBase { 26 | 27 | protected static final ChronicleLogLevel[] LOG_LEVELS = ChronicleLogLevel.values(); 28 | 29 | // ************************************************************************* 30 | // 31 | // ************************************************************************* 32 | 33 | protected static void log(Logger logger, ChronicleLogLevel level, String fmt, Object... args) { 34 | switch (level) { 35 | case TRACE: 36 | logger.log(Level.FINER, fmt, args); 37 | break; 38 | 39 | case DEBUG: 40 | logger.log(Level.FINE, fmt, args); 41 | break; 42 | 43 | case INFO: 44 | logger.log(Level.INFO, fmt, args); 45 | break; 46 | 47 | case WARN: 48 | logger.log(Level.WARNING, fmt, args); 49 | break; 50 | 51 | case ERROR: 52 | logger.log(Level.SEVERE, fmt, args); 53 | break; 54 | default: 55 | throw new UnsupportedOperationException(); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /logger-jul/src/test/resources/JulLoggerChronicleTest.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2014-2017 Chronicle Software 3 | # 4 | # https://chronicle.software 5 | # 6 | # This program is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License 16 | # along with this program. If not, see . 17 | # 18 | 19 | ################################################################################ 20 | # Common 21 | ################################################################################ 22 | 23 | chronicle.logger.base = ${java.io.tmpdir}/chronicle-jul-api 24 | 25 | chronicle.logger.root.path = ${chronicle.logger.base}/root-binary 26 | chronicle.logger.root.level = debug 27 | chronicle.logger.root.append = false 28 | 29 | chronicle.logger.logger_1.path = ${chronicle.logger.base}/logger_1 30 | chronicle.logger.logger_1.level = info 31 | chronicle.logger.logger_1.wireType = json 32 | 33 | chronicle.logger.logger_bin.path = ${chronicle.logger.base}/logger_bin 34 | chronicle.logger.logger_bin.level = trace 35 | -------------------------------------------------------------------------------- /logger-jul/src/test/resources/binary-cfg.properties: -------------------------------------------------------------------------------- 1 | 2 | # 3 | # Copyright (C) 2014-2017 Chronicle Software 4 | # 5 | # https://chronicle.software 6 | # 7 | # This program is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU Lesser General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License. 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 14 | # GNU 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, see . 18 | # 19 | 20 | handlers=java.util.logging.ConsoleHandler, net.openhft.chronicle.logger.jul.ChronicleHandler 21 | 22 | .level=ALL 23 | 24 | java.util.logging.ConsoleHandler.level=ALL 25 | java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter 26 | 27 | net.openhft.level=WARNING 28 | net.openhft.handlers=java.util.logging.ConsoleHandler 29 | 30 | ################################################################################ 31 | # BINARY 32 | ################################################################################ 33 | 34 | net.openhft.chronicle.logger.jul.ChronicleHandler.path = ${java.io.tmpdir}/chronicle-jul 35 | net.openhft.chronicle.logger.jul.ChronicleHandler.level = ALL 36 | 37 | binary-cfg.level=INFO 38 | binary-cfg.handlers=net.openhft.chronicle.logger.jul.ChronicleHandler 39 | binary-cfg.useParentHandlers=false 40 | -------------------------------------------------------------------------------- /logger-jul/src/test/resources/binary-chronicle.properties: -------------------------------------------------------------------------------- 1 | 2 | # 3 | # Copyright (C) 2014-2017 Chronicle Software 4 | # 5 | # https://chronicle.software 6 | # 7 | # This program is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU Lesser General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License. 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 14 | # GNU 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, see . 18 | # 19 | 20 | handlers=java.util.logging.ConsoleHandler, net.openhft.chronicle.logger.jul.ChronicleHandler 21 | 22 | .level=ALL 23 | 24 | java.util.logging.ConsoleHandler.level=ALL 25 | java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter 26 | 27 | net.openhft.level=WARNING 28 | net.openhft.handlers=java.util.logging.ConsoleHandler 29 | 30 | ################################################################################ 31 | # BINARY 32 | ################################################################################ 33 | 34 | net.openhft.chronicle.logger.jul.ChronicleHandler.path = ${java.io.tmpdir}/chronicle-jul/binary-chronicle 35 | net.openhft.chronicle.logger.jul.ChronicleHandler.level = ALL 36 | 37 | binary-chronicle.level=ALL 38 | binary-chronicle.handlers=net.openhft.chronicle.logger.jul.ChronicleHandler 39 | binary-chronicle.useParentHandlers=false 40 | 41 | -------------------------------------------------------------------------------- /logger-log4j-1/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 22 | 23 | 4.0.0 24 | 25 | 26 | net.openhft 27 | chronicle-logger 28 | 4.27ea2-SNAPSHOT 29 | ../pom.xml 30 | 31 | 32 | OpenHFT/Chronicle-Logger/logger-log4j-1 33 | chronicle-logger-log4j-1 34 | bundle 35 | 36 | 37 | 38 | net.openhft 39 | chronicle-logger-core 40 | 41 | 42 | 43 | 44 | org.slf4j 45 | slf4j-api 46 | 47 | 48 | org.slf4j 49 | slf4j-log4j12 50 | 1.7.33 51 | 52 | 53 | 54 | 55 | log4j 56 | log4j 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | org.apache.maven.plugins 65 | maven-surefire-plugin 66 | 67 | 1 68 | false 69 | 70 | **/*PerfTest.java 71 | 72 | 73 | ${project.build.directory} 74 | 75 | 76 | 77 | 85 | 86 | org.apache.servicemix.tooling 87 | depends-maven-plugin 88 | 89 | 90 | generate-depends-file 91 | 92 | generate-depends-file 93 | 94 | 95 | 96 | 97 | 98 | org.apache.felix 99 | maven-bundle-plugin 100 | true 101 | 102 | 103 | ${project.groupId}.${project.artifactId} 104 | OpenHFT :: ${project.artifactId} 105 | ${project.version} 106 | net.openhft.chronicle.logger.log4j1.* 107 | 108 | 109 | 110 | 114 | 115 | 116 | manifest 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 126 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 127 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 128 | master 129 | 130 | 131 | 132 | -------------------------------------------------------------------------------- /logger-log4j-1/src/main/java/net/openhft/chronicle/logger/log4j1/ChronicleAppender.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.log4j1; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogWriter; 21 | import net.openhft.chronicle.logger.DefaultChronicleLogWriter; 22 | import net.openhft.chronicle.logger.LogAppenderConfig; 23 | 24 | import java.io.IOException; 25 | 26 | public final class ChronicleAppender extends AbstractChronicleAppender { 27 | 28 | private final LogAppenderConfig config; 29 | 30 | public ChronicleAppender() { 31 | this.config = new LogAppenderConfig(); 32 | } 33 | 34 | // ************************************************************************* 35 | // Custom logging options 36 | // ************************************************************************* 37 | 38 | public void setBlockSize(int blockSize) { 39 | config.setBlockSize(blockSize); 40 | } 41 | 42 | public void setBufferCapacity(int bufferCapacity) { 43 | config.setBufferCapacity(bufferCapacity); 44 | } 45 | 46 | public String rollCycle() { 47 | return config.getRollCycle(); 48 | } 49 | 50 | public void rollCycle(String rollCycle) { 51 | config.setRollCycle(rollCycle); 52 | } 53 | 54 | @Override 55 | protected ChronicleLogWriter createWriter() throws IOException { 56 | return new DefaultChronicleLogWriter(this.config.build(this.getPath(), this.getWireType())); 57 | } 58 | 59 | // ************************************************************************* 60 | // LogAppenderConfig 61 | // ************************************************************************* 62 | 63 | LogAppenderConfig getChronicleConfig() { 64 | return this.config; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /logger-log4j-1/src/main/java/net/openhft/chronicle/logger/log4j1/internal/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This package and any and all sub-packages contains strictly internal classes for this Chronicle library. 3 | * Internal classes shall never be used directly. 4 | * 5 | * Specifically, the following actions (including, but not limited to) are not allowed 6 | * on internal classes and packages: 7 | * 8 | * Casting to 9 | * Reflection of any kind 10 | * Explicit Serialize/deserialize 11 | * 12 | * 13 | * The classes in this package and any sub-package are subject to 14 | * changes at any time for any reason. 15 | */ 16 | package net.openhft.chronicle.logger.log4j1.internal; 17 | -------------------------------------------------------------------------------- /logger-log4j-1/src/test/java/net/openhft/chronicle/logger/log4j1/Log4j1TestBase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.log4j1; 19 | 20 | import net.openhft.chronicle.core.OS; 21 | import net.openhft.chronicle.core.util.Time; 22 | import net.openhft.chronicle.logger.ChronicleLogLevel; 23 | import org.slf4j.Logger; 24 | 25 | import java.io.File; 26 | 27 | class Log4j1TestBase { 28 | 29 | // ************************************************************************* 30 | // 31 | // ************************************************************************* 32 | 33 | static final ChronicleLogLevel[] LOG_LEVELS = ChronicleLogLevel.values(); 34 | 35 | static String rootPath() { 36 | String path = System.getProperty("java.io.tmpdir"); 37 | String sep = System.getProperty("file.separator"); 38 | 39 | if (!path.endsWith(sep)) { 40 | path += sep; 41 | } 42 | 43 | return path + "chronicle-log4j1"; 44 | } 45 | 46 | static String basePath(String type) { 47 | return rootPath() 48 | + File.separator 49 | + type; 50 | } 51 | 52 | static void log(Logger logger, ChronicleLogLevel level, String fmt, Object... args) { 53 | switch (level) { 54 | case TRACE: 55 | logger.trace(fmt, args); 56 | break; 57 | 58 | case DEBUG: 59 | logger.debug(fmt, args); 60 | break; 61 | 62 | case INFO: 63 | logger.info(fmt, args); 64 | break; 65 | 66 | case WARN: 67 | logger.warn(fmt, args); 68 | break; 69 | 70 | case ERROR: 71 | logger.error(fmt, args); 72 | break; 73 | default: 74 | throw new UnsupportedOperationException(); 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /logger-log4j-1/src/test/resources/log4j.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /logger-log4j-2/src/main/java/net/openhft/chronicle/logger/log4j2/ChronicleAppender.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.log4j2; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogWriter; 21 | import net.openhft.chronicle.logger.DefaultChronicleLogWriter; 22 | import net.openhft.chronicle.logger.LogAppenderConfig; 23 | import org.apache.logging.log4j.core.Filter; 24 | import org.apache.logging.log4j.core.LogEvent; 25 | import org.apache.logging.log4j.core.config.plugins.Plugin; 26 | import org.apache.logging.log4j.core.config.plugins.PluginAttribute; 27 | import org.apache.logging.log4j.core.config.plugins.PluginElement; 28 | import org.apache.logging.log4j.core.config.plugins.PluginFactory; 29 | import org.jetbrains.annotations.NotNull; 30 | 31 | import java.io.IOException; 32 | 33 | @Plugin( 34 | name = "Chronicle", 35 | category = "Core", 36 | elementType = "appender", 37 | printObject = true) 38 | public class ChronicleAppender extends AbstractChronicleAppender { 39 | 40 | private final ChronicleCfg config; 41 | 42 | public ChronicleAppender(final String name, final Filter filter, final String path, final String wireType, final ChronicleCfg config) { 43 | super(name, filter, path, wireType); 44 | 45 | this.config = config != null ? config : new ChronicleCfg(); 46 | } 47 | 48 | // ************************************************************************* 49 | // 50 | // ************************************************************************* 51 | 52 | @PluginFactory 53 | public static ChronicleAppender createAppender( 54 | @PluginAttribute("name") final String name, 55 | @PluginAttribute("path") final String path, 56 | @PluginAttribute("wireType") final String wireType, 57 | @PluginElement("chronicleCfg") final ChronicleCfg chronicleConfig, 58 | @PluginElement("filter") final Filter filter) { 59 | if (name == null) { 60 | LOGGER.error("No name provided for ChronicleAppender"); 61 | return null; 62 | } 63 | 64 | if (path == null) { 65 | LOGGER.error("No path provided for ChronicleAppender"); 66 | return null; 67 | } 68 | 69 | return new ChronicleAppender(name, filter, path, wireType, chronicleConfig); 70 | } 71 | 72 | @Override 73 | public void doAppend(@NotNull final LogEvent event, @NotNull final ChronicleLogWriter writer) { 74 | writer.write( 75 | toChronicleLogLevel(event.getLevel()), 76 | event.getTimeMillis(), 77 | event.getThreadName(), 78 | event.getLoggerName(), 79 | event.getMessage().getFormattedMessage(), 80 | event.getThrown() 81 | ); 82 | } 83 | 84 | @Override 85 | protected ChronicleLogWriter createWriter() throws IOException { 86 | return new DefaultChronicleLogWriter(config.build(getPath(), getWireType())); 87 | } 88 | 89 | // ************************************************************************* 90 | // 91 | // ************************************************************************* 92 | 93 | protected LogAppenderConfig getChronicleConfig() { 94 | return this.config; 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /logger-log4j-2/src/main/java/net/openhft/chronicle/logger/log4j2/internal/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This package and any and all sub-packages contains strictly internal classes for this Chronicle library. 3 | * Internal classes shall never be used directly. 4 | * 5 | * Specifically, the following actions (including, but not limited to) are not allowed 6 | * on internal classes and packages: 7 | * 8 | * Casting to 9 | * Reflection of any kind 10 | * Explicit Serialize/deserialize 11 | * 12 | * 13 | * The classes in this package and any sub-package are subject to 14 | * changes at any time for any reason. 15 | */ 16 | package net.openhft.chronicle.logger.log4j2.internal; 17 | -------------------------------------------------------------------------------- /logger-log4j-2/src/test/java/net/openhft/chronicle/logger/log4j2/Log4j2TestBase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.log4j2; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogLevel; 21 | import org.apache.logging.log4j.LogManager; 22 | import org.slf4j.Logger; 23 | 24 | import java.io.File; 25 | 26 | public class Log4j2TestBase { 27 | 28 | // ************************************************************************* 29 | // 30 | // ************************************************************************* 31 | 32 | static final ChronicleLogLevel[] LOG_LEVELS = ChronicleLogLevel.values(); 33 | 34 | static String rootPath() { 35 | String path = System.getProperty("java.io.tmpdir"); 36 | String sep = System.getProperty("file.separator"); 37 | 38 | if (!path.endsWith(sep)) { 39 | path += sep; 40 | } 41 | 42 | return path + "chronicle-log4j2"; 43 | } 44 | 45 | static String basePath(String type) { 46 | return rootPath() 47 | + File.separator 48 | + type; 49 | } 50 | 51 | static void log(Logger logger, ChronicleLogLevel level, String fmt, Object... args) { 52 | switch (level) { 53 | case TRACE: 54 | logger.trace(fmt, args); 55 | break; 56 | 57 | case DEBUG: 58 | logger.debug(fmt, args); 59 | break; 60 | 61 | case INFO: 62 | logger.info(fmt, args); 63 | break; 64 | 65 | case WARN: 66 | logger.warn(fmt, args); 67 | break; 68 | 69 | case ERROR: 70 | logger.error(fmt, args); 71 | break; 72 | default: 73 | throw new UnsupportedOperationException(); 74 | } 75 | } 76 | 77 | // ************************************************************************* 78 | // 79 | // ************************************************************************* 80 | 81 | static org.apache.logging.log4j.core.Appender getAppender(String name) { 82 | final org.apache.logging.log4j.core.LoggerContext ctx = 83 | (org.apache.logging.log4j.core.LoggerContext) LogManager.getContext(); 84 | 85 | return ctx.getConfiguration().getAppender(name); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /logger-log4j-2/src/test/java/net/openhft/chronicle/logger/log4j2/Log4j2VulnerabilityTest.java: -------------------------------------------------------------------------------- 1 | package net.openhft.chronicle.logger.log4j2; 2 | 3 | import org.apache.logging.log4j.LogManager; 4 | import org.junit.BeforeClass; 5 | import org.junit.Test; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | 9 | import java.io.IOException; 10 | import java.nio.file.Files; 11 | import java.nio.file.Paths; 12 | 13 | /** 14 | * see https://blog.cloudflare.com/inside-the-log4j2-vulnerability-cve-2021-44228/ etc. 15 | * 16 | * This is not a proper unit test - just some exploratory code 17 | */ 18 | public class Log4j2VulnerabilityTest extends Log4j2TestBase { 19 | 20 | public static final String VULNERABILITY = "${jndi:ldap://localhost/xxxx}"; 21 | 22 | @BeforeClass 23 | public static void systemProperties() { 24 | System.setProperty("com.sun.jndi.rmi.object.trustURLCodebase", "true"); 25 | } 26 | 27 | /** 28 | * Run this test with -Dlog4j2.debug and you will not see any JNDI-related logging - see below 29 | */ 30 | @Test 31 | public void testVulnerability() throws IOException { 32 | final String testId = "chronicle"; 33 | final String threadId = testId + "-th"; 34 | final Logger logger = LoggerFactory.getLogger(testId); 35 | 36 | Thread.currentThread().setName(threadId); 37 | Files.createDirectories(Paths.get(basePath(testId))); 38 | 39 | logger.error(VULNERABILITY); 40 | } 41 | 42 | /** 43 | * Run this test with -Dlog4j2.debug and you will see 44 | * 45 | * {@code WARN StatusLogger Error looking up JNDI resource [ldap://localhost/xxxx]} 46 | * 47 | */ 48 | @Test 49 | public void testVulnerabilityLog4j2() { 50 | LogManager.getLogger("HelloWorld").error(VULNERABILITY); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /logger-log4j-2/src/test/resources/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | ${sys:java.io.tmpdir}/chronicle-log4j2/conf-chronicle 34 | 35 | 128 36 | 256 37 | 38 | 39 | 40 | 41 | ${sys:java.io.tmpdir}/chronicle-log4j2/chronicle 42 | 43 | FAST_HOURLY 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /logger-logback/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 22 | 23 | 4.0.0 24 | 25 | 26 | net.openhft 27 | chronicle-logger 28 | 4.27ea2-SNAPSHOT 29 | ../pom.xml 30 | 31 | 32 | OpenHFT/Chronicle-Logger/logger-logback 33 | chronicle-logger-logback 34 | bundle 35 | 36 | 37 | 38 | net.openhft 39 | chronicle-logger-core 40 | 41 | 42 | 43 | 44 | org.slf4j 45 | slf4j-api 46 | 47 | 48 | 49 | 50 | ch.qos.logback 51 | logback-classic 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | org.apache.maven.plugins 60 | maven-surefire-plugin 61 | 62 | 1 63 | false 64 | 65 | **/*PerfTest.java 66 | 67 | 68 | 69 | ${project.basedir}/src/test/resources 70 | 71 | ${project.build.directory} 72 | 73 | 74 | 75 | 83 | 84 | org.apache.servicemix.tooling 85 | depends-maven-plugin 86 | 87 | 88 | generate-depends-file 89 | 90 | generate-depends-file 91 | 92 | 93 | 94 | 95 | 96 | org.apache.felix 97 | maven-bundle-plugin 98 | true 99 | 100 | 101 | ${project.groupId}.${project.artifactId} 102 | OpenHFT :: ${project.artifactId} 103 | ${project.version} 104 | net.openhft.chronicle.logger.logback.* 105 | 106 | 107 | 108 | 112 | 113 | 114 | manifest 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 123 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 124 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 125 | master 126 | 127 | 128 | -------------------------------------------------------------------------------- /logger-logback/src/main/java/net/openhft/chronicle/logger/logback/AbstractChronicleAppender.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.logback; 19 | 20 | import ch.qos.logback.classic.Level; 21 | import ch.qos.logback.classic.spi.ILoggingEvent; 22 | import ch.qos.logback.core.Appender; 23 | import ch.qos.logback.core.filter.Filter; 24 | import ch.qos.logback.core.spi.ContextAwareBase; 25 | import ch.qos.logback.core.spi.FilterAttachableImpl; 26 | import ch.qos.logback.core.spi.FilterReply; 27 | import net.openhft.chronicle.logger.ChronicleLogLevel; 28 | import net.openhft.chronicle.logger.ChronicleLogWriter; 29 | 30 | import java.io.IOException; 31 | import java.util.List; 32 | 33 | public abstract class AbstractChronicleAppender 34 | extends ContextAwareBase 35 | implements Appender { 36 | 37 | private final FilterAttachableImpl filterAttachable; 38 | protected ChronicleLogWriter writer; 39 | private String name; 40 | private boolean started; 41 | private String path; 42 | private String wireType; 43 | 44 | protected AbstractChronicleAppender() { 45 | this.filterAttachable = new FilterAttachableImpl<>(); 46 | this.name = null; 47 | this.started = false; 48 | this.path = null; 49 | this.wireType = null; 50 | this.writer = null; 51 | } 52 | 53 | // ************************************************************************* 54 | // Custom logging options 55 | // ************************************************************************* 56 | 57 | public static ChronicleLogLevel toChronicleLogLevel(final Level level) { 58 | switch (level.levelInt) { 59 | case Level.DEBUG_INT: 60 | return ChronicleLogLevel.DEBUG; 61 | case Level.TRACE_INT: 62 | return ChronicleLogLevel.TRACE; 63 | case Level.INFO_INT: 64 | return ChronicleLogLevel.INFO; 65 | case Level.WARN_INT: 66 | return ChronicleLogLevel.WARN; 67 | case Level.ERROR_INT: 68 | return ChronicleLogLevel.ERROR; 69 | default: 70 | throw new IllegalArgumentException(level.levelInt + " not a valid level value"); 71 | } 72 | } 73 | 74 | public String getPath() { 75 | return this.path; 76 | } 77 | 78 | public void setPath(String path) { 79 | this.path = path; 80 | } 81 | 82 | public String getWireType() { 83 | return wireType; 84 | } 85 | 86 | // ************************************************************************* 87 | // Chronicle implementation 88 | // ************************************************************************* 89 | 90 | public void setWireType(String wireType) { 91 | this.wireType = wireType; 92 | } 93 | 94 | protected abstract ChronicleLogWriter createWriter() throws IOException; 95 | 96 | // ************************************************************************* 97 | // 98 | // ************************************************************************* 99 | 100 | protected abstract void doAppend(final ILoggingEvent event, final ChronicleLogWriter writer); 101 | 102 | @Override 103 | public String getName() { 104 | return name; 105 | } 106 | 107 | @Override 108 | public void setName(String name) { 109 | this.name = name; 110 | } 111 | 112 | @Override 113 | public boolean isStarted() { 114 | return started; 115 | } 116 | 117 | @Override 118 | public void addFilter(Filter newFilter) { 119 | this.filterAttachable.addFilter(newFilter); 120 | } 121 | 122 | @Override 123 | public void clearAllFilters() { 124 | this.filterAttachable.clearAllFilters(); 125 | } 126 | 127 | @Override 128 | public List> getCopyOfAttachedFiltersList() { 129 | return this.filterAttachable.getCopyOfAttachedFiltersList(); 130 | } 131 | 132 | @Override 133 | public FilterReply getFilterChainDecision(ILoggingEvent event) { 134 | return this.filterAttachable.getFilterChainDecision(event); 135 | } 136 | 137 | @Override 138 | public void start() { 139 | if (getPath() == null) { 140 | addError("Appender " + getName() + " has configuration errors and is not started!"); 141 | 142 | } else { 143 | try { 144 | this.writer = createWriter(); 145 | this.started = true; 146 | } catch (IOException e) { 147 | this.writer = null; 148 | addError("Appender " + getName() + " " + e.getMessage()); 149 | } 150 | } 151 | } 152 | 153 | @Override 154 | public void stop() { 155 | if (this.writer != null) { 156 | try { 157 | this.writer.close(); 158 | } catch (IOException e) { 159 | addError("Appender " + getName() + " " + e.getMessage()); 160 | } 161 | } 162 | 163 | this.started = false; 164 | } 165 | 166 | // ************************************************************************* 167 | // 168 | // ************************************************************************* 169 | 170 | @Override 171 | public void doAppend(final ILoggingEvent event) { 172 | if (getFilterChainDecision(event) != FilterReply.DENY) { 173 | doAppend(event, writer); 174 | } 175 | } 176 | } 177 | -------------------------------------------------------------------------------- /logger-logback/src/main/java/net/openhft/chronicle/logger/logback/ChronicleAppender.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.logback; 19 | 20 | import ch.qos.logback.classic.spi.ILoggingEvent; 21 | import ch.qos.logback.classic.spi.ThrowableProxy; 22 | import ch.qos.logback.core.joran.spi.DefaultClass; 23 | import net.openhft.chronicle.logger.ChronicleLogWriter; 24 | import net.openhft.chronicle.logger.DefaultChronicleLogWriter; 25 | import net.openhft.chronicle.logger.LogAppenderConfig; 26 | 27 | import java.io.IOException; 28 | 29 | public class ChronicleAppender extends AbstractChronicleAppender { 30 | 31 | private boolean includeCallerData; 32 | private boolean includeMDC; 33 | 34 | private LogAppenderConfig config; 35 | 36 | public ChronicleAppender() { 37 | super(); 38 | 39 | this.includeCallerData = true; 40 | this.includeMDC = true; 41 | this.config = new LogAppenderConfig(); 42 | } 43 | 44 | public LogAppenderConfig getChronicleConfig() { 45 | return this.config; 46 | } 47 | 48 | @DefaultClass(value = LogAppenderConfig.class) 49 | public void setChronicleConfig(final LogAppenderConfig config) { 50 | this.config = config; 51 | } 52 | 53 | @Override 54 | protected ChronicleLogWriter createWriter() throws IOException { 55 | return new DefaultChronicleLogWriter(this.config.build(this.getPath(), getWireType())); 56 | } 57 | 58 | // ************************************************************************* 59 | // Custom logging options 60 | // ************************************************************************* 61 | 62 | public boolean isIncludeCallerData() { 63 | return this.includeCallerData; 64 | } 65 | 66 | public void setIncludeCallerData(boolean logCallerData) { 67 | this.includeCallerData = logCallerData; 68 | } 69 | 70 | public boolean isIncludeMappedDiagnosticContext() { 71 | return this.includeMDC; 72 | } 73 | 74 | public void setIncludeMappedDiagnosticContext(boolean logMDC) { 75 | this.includeMDC = logMDC; 76 | } 77 | 78 | // ************************************************************************* 79 | // 80 | // ************************************************************************* 81 | 82 | @Override 83 | public void doAppend(final ILoggingEvent event, final ChronicleLogWriter writer) { 84 | final ThrowableProxy tp = (ThrowableProxy) event.getThrowableProxy(); 85 | 86 | writer.write( 87 | toChronicleLogLevel(event.getLevel()), 88 | event.getTimeStamp(), 89 | event.getThreadName(), 90 | event.getLoggerName(), 91 | event.getMessage(), 92 | tp != null ? tp.getThrowable() : null, 93 | event.getArgumentArray() 94 | ); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /logger-logback/src/main/java/net/openhft/chronicle/logger/logback/internal/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This package and any and all sub-packages contains strictly internal classes for this Chronicle library. 3 | * Internal classes shall never be used directly. 4 | * 5 | * Specifically, the following actions (including, but not limited to) are not allowed 6 | * on internal classes and packages: 7 | * 8 | * Casting to 9 | * Reflection of any kind 10 | * Explicit Serialize/deserialize 11 | * 12 | * 13 | * The classes in this package and any sub-package are subject to 14 | * changes at any time for any reason. 15 | */ 16 | package net.openhft.chronicle.logger.logback.internal; 17 | -------------------------------------------------------------------------------- /logger-logback/src/test/java/net/openhft/chronicle/logger/logback/LogbackChronicleProgrammaticConfigTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.logback; 19 | 20 | import ch.qos.logback.classic.Logger; 21 | import ch.qos.logback.classic.LoggerContext; 22 | import net.openhft.chronicle.core.OS; 23 | import net.openhft.chronicle.core.util.Time; 24 | import net.openhft.chronicle.logger.LogAppenderConfig; 25 | import org.junit.Test; 26 | import org.slf4j.LoggerFactory; 27 | 28 | public class LogbackChronicleProgrammaticConfigTest extends LogbackTestBase { 29 | 30 | @Test 31 | public void testConfig() { 32 | LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory(); 33 | context.reset(); 34 | 35 | ChronicleAppender appender = new ChronicleAppender(); 36 | appender.setPath(OS.getTarget() + "/clog" + Time.uniqueId()); 37 | appender.setChronicleConfig(new LogAppenderConfig()); 38 | appender.setContext(context); 39 | appender.start(); 40 | 41 | Logger logger = context.getLogger(Logger.ROOT_LOGGER_NAME); 42 | logger.addAppender(appender); 43 | 44 | logger.info("Hello World"); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /logger-logback/src/test/java/net/openhft/chronicle/logger/logback/LogbackIndexedChronicleConfigTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.logback; 19 | 20 | import ch.qos.logback.classic.spi.ILoggingEvent; 21 | import org.junit.Before; 22 | import org.junit.Test; 23 | 24 | import java.io.IOException; 25 | 26 | import static org.junit.Assert.*; 27 | 28 | public class LogbackIndexedChronicleConfigTest extends LogbackTestBase { 29 | 30 | @Before 31 | public void setup() { 32 | System.setProperty( 33 | "logback.configurationFile", 34 | System.getProperty("resources.path") + "/logback-chronicle-config.xml" 35 | ); 36 | } 37 | 38 | // ************************************************************************* 39 | // 40 | // ************************************************************************* 41 | 42 | @Test 43 | public void testBinaryIndexedChronicleAppenderConfig() throws IOException { 44 | final String loggerName = "config-binary-chronicle"; 45 | final String appenderName = "CONFIG-BINARY-CHRONICLE"; 46 | 47 | final ch.qos.logback.classic.Logger logger = getLoggerContext().getLogger(loggerName); 48 | assertNotNull(logger); 49 | 50 | final ch.qos.logback.core.Appender appender = logger.getAppender(appenderName); 51 | assertNotNull(appender); 52 | assertTrue(appender instanceof ChronicleAppender); 53 | 54 | ChronicleAppender ba = (ChronicleAppender) appender; 55 | assertEquals(128, ba.getChronicleConfig().getBlockSize()); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /logger-logback/src/test/java/net/openhft/chronicle/logger/logback/LogbackTestBase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.logback; 19 | 20 | import ch.qos.logback.classic.LoggerContext; 21 | import net.openhft.chronicle.core.OS; 22 | import net.openhft.chronicle.core.util.Time; 23 | import net.openhft.chronicle.logger.ChronicleLogLevel; 24 | import org.slf4j.Logger; 25 | import org.slf4j.LoggerFactory; 26 | 27 | public class LogbackTestBase { 28 | 29 | // ************************************************************************* 30 | // 31 | // ************************************************************************* 32 | 33 | static final ChronicleLogLevel[] LOG_LEVELS = ChronicleLogLevel.values(); 34 | 35 | static String rootPath() { 36 | String path = System.getProperty("java.io.tmpdir"); 37 | String sep = System.getProperty("file.separator"); 38 | 39 | if (!path.endsWith(sep)) { 40 | path += sep; 41 | } 42 | 43 | return path + "chronicle-logback"; 44 | } 45 | 46 | static String basePath(String type) { 47 | return rootPath() 48 | + System.getProperty("file.separator") 49 | + type; 50 | } 51 | 52 | static void log(Logger logger, ChronicleLogLevel level, String fmt, Object... args) { 53 | switch (level) { 54 | case TRACE: 55 | logger.trace(fmt, args); 56 | break; 57 | 58 | case DEBUG: 59 | logger.debug(fmt, args); 60 | break; 61 | 62 | case INFO: 63 | logger.info(fmt, args); 64 | break; 65 | 66 | case WARN: 67 | logger.warn(fmt, args); 68 | break; 69 | 70 | case ERROR: 71 | logger.error(fmt, args); 72 | break; 73 | default: 74 | throw new UnsupportedOperationException(); 75 | } 76 | } 77 | 78 | // ************************************************************************* 79 | // 80 | // ************************************************************************* 81 | 82 | LoggerContext getLoggerContext() { 83 | return (LoggerContext) LoggerFactory.getILoggerFactory(); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /logger-logback/src/test/resources/logback-chronicle-binary-appender.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 22 | 23 | 25 | 26 | %d %contextName [%t] %level %logger{36} - %msg%n 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 36 | ${java.io.tmpdir}/chronicle-logback/binary-chronicle 37 | false 38 | false 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /logger-logback/src/test/resources/logback-chronicle-config.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 22 | 23 | 25 | 26 | %d %contextName [%t] %level %logger{36} - %msg%n 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 36 | ${java.io.tmpdir}/chronicle-logback/config-binary-chronicle 37 | false 38 | false 39 | 40 | 41 | 128 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /logger-slf4j-2/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 22 | 23 | 4.0.0 24 | 25 | 26 | net.openhft 27 | chronicle-logger 28 | 4.27ea2-SNAPSHOT 29 | ../pom.xml 30 | 31 | 32 | OpenHFT/Chronicle-Logger/logger-slf4j-2 33 | chronicle-logger-slf4j-2 34 | bundle 35 | 36 | 37 | 38 | net.openhft 39 | chronicle-logger-core 40 | 41 | 42 | 43 | 44 | org.slf4j 45 | slf4j-api 46 | 2.0.0 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | org.apache.maven.plugins 55 | maven-surefire-plugin 56 | 57 | 58 | **/*PerfTest.java 59 | 60 | 61 | ${project.build.directory} 62 | 63 | 64 | 65 | 73 | 74 | org.apache.servicemix.tooling 75 | depends-maven-plugin 76 | 77 | 78 | generate-depends-file 79 | 80 | generate-depends-file 81 | 82 | 83 | 84 | 85 | 86 | org.apache.felix 87 | maven-bundle-plugin 88 | true 89 | 90 | 91 | ${project.groupId}.${project.artifactId} 92 | OpenHFT :: ${project.artifactId} 93 | ${project.version} 94 | net.openhft.chronicle.logger.slf4j.* 95 | 96 | 97 | 98 | 102 | 103 | 104 | manifest 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 114 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 115 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 116 | master 117 | 118 | 119 | 120 | -------------------------------------------------------------------------------- /logger-slf4j-2/src/main/java/net/openhft/chronicle/logger/slf4j2/ChronicleLoggerFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.slf4j2; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogManager; 21 | import net.openhft.chronicle.logger.ChronicleLogWriter; 22 | import org.slf4j.ILoggerFactory; 23 | import org.slf4j.Logger; 24 | import org.slf4j.helpers.NOPLogger; 25 | import org.slf4j.impl.SimpleLogger; 26 | 27 | import java.util.Map; 28 | import java.util.concurrent.ConcurrentHashMap; 29 | 30 | /** 31 | * Simple implementation of Logger that sends all enabled slf4j messages, 32 | * for all defined loggers, to one or more VanillaChronicle.. 33 | * 34 | * To configure this sl4j binding you need to specify the location of a properties 35 | * files via system properties: 36 | * {@code -Dchronicle.logger.properties=${pathOfYourPropertiesFile}} 37 | * 38 | * The following system properties are supported to configure the behavior of this 39 | * logger: 40 | * 41 | * {@code chronicle.logger.root.path} 42 | * {@code chronicle.logger.root.level} 43 | * {@code chronicle.logger.root.append} 44 | * 45 | */ 46 | public class ChronicleLoggerFactory implements ILoggerFactory { 47 | private final Map loggers; 48 | private final ChronicleLogManager manager; 49 | 50 | // ************************************************************************* 51 | // 52 | // ************************************************************************* 53 | 54 | /** 55 | * c-tor 56 | */ 57 | public ChronicleLoggerFactory() { 58 | this.loggers = new ConcurrentHashMap<>(); 59 | this.manager = ChronicleLogManager.getInstance(); 60 | } 61 | 62 | // ************************************************************************* 63 | // for testing 64 | // ************************************************************************* 65 | 66 | /** 67 | * Return an appropriate {@link ChronicleLogger} instance by name. 68 | */ 69 | @Override 70 | public Logger getLogger(String name) { 71 | try { 72 | return doGetLogger(name); 73 | } catch (Exception e) { 74 | System.err.println("Unable to initialize chronicle-logger-slf4j (" + name + ")\n " + e.getMessage()); 75 | e.printStackTrace(); 76 | } 77 | 78 | return NOPLogger.NOP_LOGGER; 79 | } 80 | 81 | // ************************************************************************* 82 | // 83 | // ************************************************************************* 84 | 85 | synchronized void reload() { 86 | this.loggers.clear(); 87 | this.manager.reload(); 88 | } 89 | 90 | private synchronized Logger doGetLogger(String name) { 91 | Logger logger = loggers.get(name); 92 | if (logger == null) { 93 | if (name != null && name.startsWith("net.openhft")) { 94 | SimpleLogger.lazyInit(); 95 | logger = new SimpleLogger(name); 96 | } else { 97 | final ChronicleLogWriter writer = manager.getWriter(name); 98 | logger = new ChronicleLogger(writer, name, manager.cfg().getLevel(name)); 99 | } 100 | loggers.put(name, logger); 101 | } 102 | 103 | return logger; 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /logger-slf4j-2/src/main/java/net/openhft/chronicle/logger/slf4j2/internal/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This package and any and all sub-packages contains strictly internal classes for this Chronicle library. 3 | * Internal classes shall never be used directly. 4 | * 5 | * Specifically, the following actions (including, but not limited to) are not allowed 6 | * on internal classes and packages: 7 | * 8 | * Casting to 9 | * Reflection of any kind 10 | * Explicit Serialize/deserialize 11 | * 12 | * 13 | * The classes in this package and any sub-package are subject to 14 | * changes at any time for any reason. 15 | */ 16 | package net.openhft.chronicle.logger.slf4j2.internal; 17 | -------------------------------------------------------------------------------- /logger-slf4j-2/src/main/java/org/slf4j/impl/ChronicleServiceProvider.java: -------------------------------------------------------------------------------- 1 | package org.slf4j.impl; 2 | 3 | import net.openhft.chronicle.logger.slf4j2.ChronicleLoggerFactory; 4 | import org.slf4j.ILoggerFactory; 5 | import org.slf4j.IMarkerFactory; 6 | import org.slf4j.helpers.BasicMarkerFactory; 7 | import org.slf4j.helpers.NOPMDCAdapter; 8 | import org.slf4j.spi.MDCAdapter; 9 | import org.slf4j.spi.SLF4JServiceProvider; 10 | 11 | public class ChronicleServiceProvider implements SLF4JServiceProvider { 12 | 13 | /** 14 | * Declare the version of the SLF4J API this implementation is compiled against. 15 | * The value of this field is modified with each major release. 16 | */ 17 | // to avoid constant folding by the compiler, this field must *not* be final 18 | public static String REQUESTED_API_VERSION = "2.0.99"; // !final 19 | 20 | public ChronicleServiceProvider() {} 21 | /** 22 | * The ILoggerFactory instance returned by the {@link #getLoggerFactory} 23 | * method should always be the same object 24 | */ 25 | private ILoggerFactory loggerFactory; 26 | 27 | private IMarkerFactory markerFactory; 28 | private MDCAdapter mdcAdapter; 29 | 30 | @Override 31 | public ILoggerFactory getLoggerFactory() { 32 | return loggerFactory; 33 | } 34 | 35 | @Override 36 | public IMarkerFactory getMarkerFactory() { 37 | return markerFactory; 38 | } 39 | 40 | @Override 41 | public MDCAdapter getMDCAdapter() { 42 | return mdcAdapter; 43 | } 44 | 45 | @Override 46 | public String getRequestedApiVersion() { 47 | return REQUESTED_API_VERSION; 48 | } 49 | 50 | @Override 51 | public void initialize() { 52 | loggerFactory = new ChronicleLoggerFactory(); 53 | markerFactory = new BasicMarkerFactory(); 54 | mdcAdapter = new NOPMDCAdapter(); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /logger-slf4j-2/src/main/java/org/slf4j/impl/OutputChoice.java: -------------------------------------------------------------------------------- 1 | package org.slf4j.impl; 2 | 3 | import java.io.PrintStream; 4 | 5 | /** 6 | * This class encapsulates the user's choice of output target. 7 | * 8 | * @author Ceki Gülcü 9 | * 10 | */ 11 | class OutputChoice { 12 | 13 | enum OutputChoiceType { 14 | SYS_OUT, CACHED_SYS_OUT, SYS_ERR, CACHED_SYS_ERR, FILE; 15 | } 16 | 17 | final OutputChoiceType outputChoiceType; 18 | final PrintStream targetPrintStream; 19 | 20 | OutputChoice(OutputChoiceType outputChoiceType) { 21 | if (outputChoiceType == OutputChoiceType.FILE) { 22 | throw new IllegalArgumentException(); 23 | } 24 | this.outputChoiceType = outputChoiceType; 25 | if (outputChoiceType == OutputChoiceType.CACHED_SYS_OUT) { 26 | this.targetPrintStream = System.out; 27 | } else if (outputChoiceType == OutputChoiceType.CACHED_SYS_ERR) { 28 | this.targetPrintStream = System.err; 29 | } else { 30 | this.targetPrintStream = null; 31 | } 32 | } 33 | 34 | OutputChoice(PrintStream printStream) { 35 | this.outputChoiceType = OutputChoiceType.FILE; 36 | this.targetPrintStream = printStream; 37 | } 38 | 39 | PrintStream getTargetPrintStream() { 40 | switch (outputChoiceType) { 41 | case SYS_OUT: 42 | return System.out; 43 | case SYS_ERR: 44 | return System.err; 45 | case CACHED_SYS_ERR: 46 | case CACHED_SYS_OUT: 47 | case FILE: 48 | return targetPrintStream; 49 | default: 50 | throw new IllegalArgumentException(); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /logger-slf4j-2/src/main/resources/META-INF/services/org.slf4j.spi.SLF4JServiceProvider: -------------------------------------------------------------------------------- 1 | org.slf4j.impl.ChronicleServiceProvider 2 | -------------------------------------------------------------------------------- /logger-slf4j-2/src/test/java/net/openhft/chronicle/logger/slf4j2/ChronicleLoggingConfigTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.slf4j2; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogConfig; 21 | import org.junit.Test; 22 | 23 | import static org.junit.Assert.assertNotNull; 24 | 25 | public class ChronicleLoggingConfigTest { 26 | @Test 27 | public void testLoadClasspathIndexed() { 28 | System.setProperty("chronicle.logger.properties", "chronicle.logger.properties"); 29 | assertLoadsValidConfig(); 30 | } 31 | 32 | private void assertLoadsValidConfig() { 33 | ChronicleLogConfig config = ChronicleLogConfig.load(); 34 | assertNotNull("unable to load config", config); 35 | assertNotNull("is not a valid config", config.getAppenderConfig()); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /logger-slf4j-2/src/test/java/net/openhft/chronicle/logger/slf4j2/Slf4jChronicleConfigurationTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.slf4j2; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogConfig; 21 | import net.openhft.chronicle.logger.ChronicleLogLevel; 22 | import org.junit.Test; 23 | 24 | import java.io.File; 25 | import java.util.Properties; 26 | 27 | import static org.junit.Assert.assertEquals; 28 | import static org.junit.Assert.assertNotNull; 29 | 30 | public class Slf4jChronicleConfigurationTest extends Slf4jTestBase { 31 | 32 | @Test 33 | public void testLoadProperties() { 34 | final String cfgPath = "chronicle.logger.properties"; 35 | final ChronicleLogConfig cfg = ChronicleLogConfig.load(cfgPath); 36 | 37 | assertNotNull(cfg); 38 | 39 | assertEquals( 40 | new File(basePath("root")), 41 | new File(cfg.getString(ChronicleLogConfig.KEY_PATH))); 42 | assertEquals( 43 | ChronicleLogLevel.DEBUG.toString(), 44 | cfg.getString(ChronicleLogConfig.KEY_LEVEL).toUpperCase()); 45 | assertEquals("false", cfg.getString(ChronicleLogConfig.KEY_APPEND)); 46 | assertEquals( 47 | new File(basePath("logger_1")), 48 | new File(cfg.getString("logger_1", ChronicleLogConfig.KEY_PATH))); 49 | assertEquals( 50 | ChronicleLogLevel.INFO.toString(), 51 | cfg.getString("logger_1", ChronicleLogConfig.KEY_LEVEL).toUpperCase()); 52 | assertEquals( 53 | ChronicleLogLevel.DEBUG.toString(), 54 | cfg.getString("readwrite", ChronicleLogConfig.KEY_LEVEL).toUpperCase()); 55 | } 56 | 57 | @Test 58 | public void testLoadConfig() { 59 | final Properties properties = new Properties(); 60 | properties.setProperty("chronicle.logger.root.cfg.blockSize", "256"); 61 | 62 | final ChronicleLogConfig clc = ChronicleLogConfig.load(properties); 63 | assertNotNull(clc.getAppenderConfig()); 64 | 65 | assertEquals(256, clc.getAppenderConfig().getBlockSize()); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /logger-slf4j-2/src/test/java/net/openhft/chronicle/logger/slf4j2/Slf4jChronicleLoggerPerfTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.slf4j2; 19 | 20 | import net.openhft.chronicle.core.io.IOTools; 21 | import org.apache.commons.lang3.StringUtils; 22 | import org.junit.After; 23 | import org.junit.Before; 24 | import org.junit.Ignore; 25 | import org.junit.Test; 26 | import org.slf4j.Logger; 27 | import org.slf4j.LoggerFactory; 28 | 29 | import java.util.concurrent.ExecutorService; 30 | import java.util.concurrent.Executors; 31 | import java.util.concurrent.TimeUnit; 32 | 33 | @Ignore 34 | public class Slf4jChronicleLoggerPerfTest extends Slf4jTestBase { 35 | 36 | // ************************************************************************* 37 | // 38 | // ************************************************************************* 39 | 40 | @Before 41 | public void setUp() { 42 | System.setProperty( 43 | "chronicle.logger.properties", 44 | "chronicle.logger.perf.properties"); 45 | 46 | getChronicleLoggerFactory().reload(); 47 | } 48 | 49 | @After 50 | public void tearDown() { 51 | IOTools.deleteDirWithFiles(basePath()); 52 | } 53 | 54 | // ************************************************************************* 55 | // Single Thread 56 | // ************************************************************************* 57 | 58 | @Test 59 | public void testSingleThreadLogging1() { 60 | Thread.currentThread().setName("perf-plain"); 61 | 62 | final String testId = "perf-chronicle"; 63 | final Logger clogger = LoggerFactory.getLogger(testId); 64 | final long items = 1000000; 65 | 66 | warmup(clogger); 67 | 68 | for (int s = 64; s <= 1024; s += 64) { 69 | final String staticStr = StringUtils.leftPad("", s, 'X'); 70 | 71 | long cStart1 = System.nanoTime(); 72 | 73 | for (int i = 1; i <= items; i++) { 74 | clogger.info(staticStr); 75 | } 76 | 77 | long cEnd1 = System.nanoTime(); 78 | 79 | System.out.printf("items=%03d size=%04d => chronology=%.3f ms, chronology-average=%.3f us\n", 80 | items, 81 | staticStr.length(), 82 | (cEnd1 - cStart1) / 1e6, 83 | (cEnd1 - cStart1) / items / 1e3); 84 | } 85 | } 86 | 87 | @Test 88 | public void testSingleThreadLogging2() { 89 | Thread.currentThread().setName("perf-plain"); 90 | 91 | final String testId = "perf-chronicle"; 92 | final Logger clogger = LoggerFactory.getLogger(testId); 93 | final long items = 1000000; 94 | final String strFmt = StringUtils.leftPad("> v1={}, v2={}, v3={}", 32, 'X'); 95 | 96 | warmup(clogger); 97 | 98 | for (int n = 0; n < 10; n++) { 99 | long cStart1 = System.nanoTime(); 100 | 101 | for (int i = 1; i <= items; i++) { 102 | clogger.info(strFmt, i, i * 10, i / 16); 103 | } 104 | 105 | long cEnd1 = System.nanoTime(); 106 | 107 | System.out.printf("items=%03d => chronology=%.3f ms, chronology-average=%.3f us\n", 108 | items, 109 | (cEnd1 - cStart1) / 1e6, 110 | (cEnd1 - cStart1) / items / 1e3); 111 | } 112 | } 113 | 114 | // ************************************************************************* 115 | // Multi Thread 116 | // ************************************************************************* 117 | 118 | @Test 119 | public void testMultiThreadLogging() throws InterruptedException { 120 | warmup(LoggerFactory.getLogger("perf-chronicle")); 121 | 122 | final int RUNS = 1000000; 123 | final int THREADS = 10; 124 | 125 | for (int size : new int[]{64, 128, 256}) { 126 | { 127 | final long start = System.nanoTime(); 128 | 129 | ExecutorService es = Executors.newFixedThreadPool(THREADS); 130 | for (int t = 0; t < THREADS; t++) { 131 | es.submit(new RunnableLogger(RUNS, size, "perf-chronicle")); 132 | } 133 | 134 | es.shutdown(); 135 | es.awaitTermination(5, TimeUnit.SECONDS); 136 | 137 | final long time = System.nanoTime() - start; 138 | 139 | System.out.printf("ChronicleLog.MT (runs=%d, min size=%03d, elapsed=%.3f ms) took an average of %.3f us per entry\n", 140 | RUNS, 141 | size, 142 | time / 1e6, 143 | time / 1e3 / (RUNS * THREADS) 144 | ); 145 | } 146 | } 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /logger-slf4j-2/src/test/java/net/openhft/chronicle/logger/slf4j2/Slf4jTestBase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.slf4j2; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogLevel; 21 | import net.openhft.chronicle.logger.slf4j2.ChronicleLoggerFactory; 22 | import org.apache.commons.lang3.StringUtils; 23 | import org.slf4j.Logger; 24 | import org.slf4j.LoggerFactory; 25 | import org.slf4j.impl.ChronicleServiceProvider; 26 | 27 | class Slf4jTestBase { 28 | 29 | // ************************************************************************* 30 | // 31 | // ************************************************************************* 32 | 33 | static final ChronicleLogLevel[] LOG_LEVELS = ChronicleLogLevel.values(); 34 | 35 | static String basePath() { 36 | String path = System.getProperty("java.io.tmpdir"); 37 | String sep = System.getProperty("file.separator"); 38 | 39 | if (!path.endsWith(sep)) { 40 | path += sep; 41 | } 42 | 43 | return path + "chronicle-slf4j"; 44 | } 45 | 46 | static String basePath(String loggerName) { 47 | return basePath() 48 | + System.getProperty("file.separator") 49 | + loggerName; 50 | } 51 | 52 | static void log(Logger logger, ChronicleLogLevel level, String fmt, Object... args) { 53 | switch (level) { 54 | case TRACE: 55 | logger.trace(fmt, args); 56 | break; 57 | 58 | case DEBUG: 59 | logger.debug(fmt, args); 60 | break; 61 | 62 | case INFO: 63 | logger.info(fmt, args); 64 | break; 65 | 66 | case WARN: 67 | logger.warn(fmt, args); 68 | break; 69 | 70 | case ERROR: 71 | logger.error(fmt, args); 72 | break; 73 | default: 74 | throw new UnsupportedOperationException(); 75 | } 76 | } 77 | 78 | static void warmup(Logger logger) { 79 | for (int i = 0; i < 10; i++) { 80 | logger.info("warmup"); 81 | } 82 | } 83 | 84 | // ************************************************************************* 85 | // 86 | // ************************************************************************* 87 | 88 | /** 89 | * @return the ChronicleLoggerFactory singleton 90 | */ 91 | ChronicleLoggerFactory getChronicleLoggerFactory() { 92 | ChronicleServiceProvider provider = new ChronicleServiceProvider(); 93 | provider.initialize(); 94 | return (ChronicleLoggerFactory) provider.getLoggerFactory(); 95 | } 96 | 97 | // ************************************************************************* 98 | // 99 | // ************************************************************************* 100 | 101 | protected final class RunnableLogger implements Runnable { 102 | private final Logger logger; 103 | private final int runs; 104 | private final String fmt; 105 | private final String fmtBase = " > val1={}, val2={}, val3={}"; 106 | 107 | public RunnableLogger(int runs, int pad, String loggerName) { 108 | this.logger = LoggerFactory.getLogger(loggerName); 109 | this.runs = runs; 110 | this.fmt = StringUtils.rightPad(fmtBase, pad + fmtBase.length() - (4 + 8 + 8), "X"); 111 | } 112 | 113 | @Override 114 | public void run() { 115 | for (int i = 0; i < this.runs; i++) { 116 | this.logger.info(fmt, i, i * 7L, i / 16.0); 117 | } 118 | } 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /logger-slf4j-2/src/test/resources/chronicle.logger.perf.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2014-2017 Chronicle Software 3 | # 4 | # https://chronicle.software 5 | # 6 | # This program is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License 16 | # along with this program. If not, see . 17 | # 18 | 19 | chronicle.logger.base = ${java.io.tmpdir}/chronicle-slf4j 20 | 21 | chronicle.logger.root.path = ${chronicle.logger.base}/perf 22 | chronicle.logger.root.level = debug 23 | chronicle.logger.root.append = false 24 | -------------------------------------------------------------------------------- /logger-slf4j-2/src/test/resources/chronicle.logger.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2014-2017 Chronicle Software 3 | # 4 | # https://chronicle.software 5 | # 6 | # This program is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License 16 | # along with this program. If not, see . 17 | # 18 | 19 | ################################################################################ 20 | # Common 21 | ################################################################################ 22 | 23 | chronicle.logger.base = ${java.io.tmpdir}/chronicle-slf4j 24 | chronicle.logger.root.path = ${chronicle.logger.base}/root 25 | chronicle.logger.root.level = debug 26 | chronicle.logger.root.append = false 27 | 28 | ################################################################################ 29 | # Loggers 30 | ################################################################################ 31 | 32 | # logger : Logger1 33 | chronicle.logger.logger_1.path = ${chronicle.logger.base}/logger_1 34 | chronicle.logger.logger_1.level = info 35 | 36 | # logger : impl 37 | chronicle.logger.readwrite.path = ${chronicle.logger.base}/readwrite 38 | -------------------------------------------------------------------------------- /logger-slf4j/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 22 | 23 | 4.0.0 24 | 25 | 26 | net.openhft 27 | chronicle-logger 28 | 4.27ea2-SNAPSHOT 29 | ../pom.xml 30 | 31 | 32 | OpenHFT/Chronicle-Logger/logger-slf4j 33 | chronicle-logger-slf4j 34 | bundle 35 | 36 | 37 | 38 | net.openhft 39 | chronicle-logger-core 40 | 41 | 42 | 43 | 44 | org.slf4j 45 | slf4j-api 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | org.apache.maven.plugins 54 | maven-surefire-plugin 55 | 56 | 57 | **/*PerfTest.java 58 | 59 | 60 | ${project.build.directory} 61 | 62 | 63 | 64 | 72 | 73 | org.apache.servicemix.tooling 74 | depends-maven-plugin 75 | 76 | 77 | generate-depends-file 78 | 79 | generate-depends-file 80 | 81 | 82 | 83 | 84 | 85 | org.apache.felix 86 | maven-bundle-plugin 87 | true 88 | 89 | 90 | ${project.groupId}.${project.artifactId} 91 | OpenHFT :: ${project.artifactId} 92 | ${project.version} 93 | net.openhft.chronicle.logger.slf4j.* 94 | 95 | 96 | 97 | 101 | 102 | 103 | manifest 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 113 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 114 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 115 | master 116 | 117 | 118 | 119 | -------------------------------------------------------------------------------- /logger-slf4j/src/main/java/net/openhft/chronicle/logger/slf4j/ChronicleLoggerFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.slf4j; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogManager; 21 | import net.openhft.chronicle.logger.ChronicleLogWriter; 22 | import org.slf4j.ILoggerFactory; 23 | import org.slf4j.Logger; 24 | import org.slf4j.helpers.NOPLogger; 25 | import org.slf4j.impl.SimpleLogger; 26 | 27 | import java.util.Map; 28 | import java.util.concurrent.ConcurrentHashMap; 29 | 30 | /** 31 | * Simple implementation of Logger that sends all enabled slf4j messages, 32 | * for all defined loggers, to one or more VanillaChronicle.. 33 | * 34 | * To configure this sl4j binding you need to specify the location of a properties 35 | * files via system properties: 36 | * {@code -Dchronicle.logger.properties=${pathOfYourPropertiesFile}} 37 | * 38 | * The following system properties are supported to configure the behavior of this 39 | * logger: 40 | * 41 | * {@code chronicle.logger.root.path} 42 | * {@code chronicle.logger.root.level} 43 | * {@code chronicle.logger.root.append} 44 | * 45 | */ 46 | public class ChronicleLoggerFactory implements ILoggerFactory { 47 | private final Map loggers; 48 | private final ChronicleLogManager manager; 49 | 50 | // ************************************************************************* 51 | // 52 | // ************************************************************************* 53 | 54 | /** 55 | * c-tor 56 | */ 57 | public ChronicleLoggerFactory() { 58 | this.loggers = new ConcurrentHashMap<>(); 59 | this.manager = ChronicleLogManager.getInstance(); 60 | } 61 | 62 | // ************************************************************************* 63 | // for testing 64 | // ************************************************************************* 65 | 66 | /** 67 | * Return an appropriate {@link ChronicleLogger} instance by name. 68 | */ 69 | @Override 70 | public Logger getLogger(String name) { 71 | try { 72 | return doGetLogger(name); 73 | } catch (Exception e) { 74 | System.err.println("Unable to initialize chronicle-logger-slf4j (" + name + ")\n " + e.getMessage()); 75 | e.printStackTrace(); 76 | } 77 | 78 | return NOPLogger.NOP_LOGGER; 79 | } 80 | 81 | // ************************************************************************* 82 | // 83 | // ************************************************************************* 84 | 85 | synchronized void reload() { 86 | this.loggers.clear(); 87 | this.manager.reload(); 88 | } 89 | 90 | private synchronized Logger doGetLogger(String name) { 91 | Logger logger = loggers.get(name); 92 | if (logger == null) { 93 | if (name != null && name.startsWith("net.openhft")) { 94 | SimpleLogger.lazyInit(); 95 | logger = new SimpleLogger(name); 96 | } else { 97 | final ChronicleLogWriter writer = manager.getWriter(name); 98 | logger = new ChronicleLogger(writer, name, manager.cfg().getLevel(name)); 99 | } 100 | loggers.put(name, logger); 101 | } 102 | 103 | return logger; 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /logger-slf4j/src/main/java/net/openhft/chronicle/logger/slf4j/internal/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This package and any and all sub-packages contains strictly internal classes for this Chronicle library. 3 | * Internal classes shall never be used directly. 4 | * 5 | * Specifically, the following actions (including, but not limited to) are not allowed 6 | * on internal classes and packages: 7 | * 8 | * Casting to 9 | * Reflection of any kind 10 | * Explicit Serialize/deserialize 11 | * 12 | * 13 | * The classes in this package and any sub-package are subject to 14 | * changes at any time for any reason. 15 | */ 16 | package net.openhft.chronicle.logger.slf4j.internal; 17 | -------------------------------------------------------------------------------- /logger-slf4j/src/main/java/org/slf4j/impl/OutputChoice.java: -------------------------------------------------------------------------------- 1 | package org.slf4j.impl; 2 | 3 | import java.io.PrintStream; 4 | 5 | /** 6 | * This class encapsulates the user's choice of output target. 7 | * 8 | * @author Ceki Gülcü 9 | * 10 | */ 11 | class OutputChoice { 12 | 13 | enum OutputChoiceType { 14 | SYS_OUT, CACHED_SYS_OUT, SYS_ERR, CACHED_SYS_ERR, FILE; 15 | } 16 | 17 | final OutputChoiceType outputChoiceType; 18 | final PrintStream targetPrintStream; 19 | 20 | OutputChoice(OutputChoiceType outputChoiceType) { 21 | if (outputChoiceType == OutputChoiceType.FILE) { 22 | throw new IllegalArgumentException(); 23 | } 24 | this.outputChoiceType = outputChoiceType; 25 | if (outputChoiceType == OutputChoiceType.CACHED_SYS_OUT) { 26 | this.targetPrintStream = System.out; 27 | } else if (outputChoiceType == OutputChoiceType.CACHED_SYS_ERR) { 28 | this.targetPrintStream = System.err; 29 | } else { 30 | this.targetPrintStream = null; 31 | } 32 | } 33 | 34 | OutputChoice(PrintStream printStream) { 35 | this.outputChoiceType = OutputChoiceType.FILE; 36 | this.targetPrintStream = printStream; 37 | } 38 | 39 | PrintStream getTargetPrintStream() { 40 | switch (outputChoiceType) { 41 | case SYS_OUT: 42 | return System.out; 43 | case SYS_ERR: 44 | return System.err; 45 | case CACHED_SYS_ERR: 46 | case CACHED_SYS_OUT: 47 | case FILE: 48 | return targetPrintStream; 49 | default: 50 | throw new IllegalArgumentException(); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /logger-slf4j/src/main/java/org/slf4j/impl/StaticLoggerBinder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.slf4j.impl; 19 | 20 | import net.openhft.chronicle.logger.slf4j.ChronicleLoggerFactory; 21 | import org.slf4j.ILoggerFactory; 22 | import org.slf4j.spi.LoggerFactoryBinder; 23 | 24 | public class StaticLoggerBinder implements LoggerFactoryBinder { 25 | 26 | private static final StaticLoggerBinder SINGLETON = new StaticLoggerBinder(); 27 | private static final String loggerFactoryClassStr = ChronicleLoggerFactory.class.getName(); 28 | /** 29 | * Declare the version of the SLF4J API this implementation is compiled 30 | * against. The value of this field is usually modified with each release. 31 | */ 32 | // to avoid constant folding by the compiler, this field must *not* be final 33 | public static String REQUESTED_API_VERSION = "1.7.30"; // !final 34 | /** 35 | * The ILoggerFactory instance returned by the {@link #getLoggerFactory} 36 | * method should always be the same object 37 | */ 38 | private final ILoggerFactory loggerFactory; 39 | 40 | /** 41 | * c-tor 42 | */ 43 | private StaticLoggerBinder() { 44 | loggerFactory = new ChronicleLoggerFactory(); 45 | } 46 | 47 | /** 48 | * Return the singleton of this class. 49 | * 50 | * @return the StaticLoggerBinder singleton 51 | */ 52 | public static final StaticLoggerBinder getSingleton() { 53 | return SINGLETON; 54 | } 55 | 56 | @Override 57 | public ILoggerFactory getLoggerFactory() { 58 | return loggerFactory; 59 | } 60 | 61 | @Override 62 | public String getLoggerFactoryClassStr() { 63 | return loggerFactoryClassStr; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /logger-slf4j/src/main/java/org/slf4j/impl/StaticMarkerBinder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.slf4j.impl; 19 | 20 | import org.slf4j.IMarkerFactory; 21 | import org.slf4j.helpers.BasicMarkerFactory; 22 | import org.slf4j.spi.MarkerFactoryBinder; 23 | 24 | /** 25 | * The binding of {@link org.slf4j.MarkerFactory} class with an actual instance of 26 | * {@link IMarkerFactory} is performed using information returned by this class. 27 | * 28 | * @author Ceki Gülcü 29 | */ 30 | public class StaticMarkerBinder implements MarkerFactoryBinder { 31 | 32 | /** 33 | * The unique instance of this class. 34 | */ 35 | public static final StaticMarkerBinder SINGLETON = new StaticMarkerBinder(); 36 | 37 | final IMarkerFactory markerFactory = new BasicMarkerFactory(); 38 | 39 | private StaticMarkerBinder() { 40 | } 41 | 42 | /** 43 | * Currently this method always returns an instance of 44 | * {@link BasicMarkerFactory}. 45 | */ 46 | @Override 47 | public IMarkerFactory getMarkerFactory() { 48 | return markerFactory; 49 | } 50 | 51 | /** 52 | * Currently, this method returns the class name of 53 | * {@link BasicMarkerFactory}. 54 | */ 55 | @Override 56 | public String getMarkerFactoryClassStr() { 57 | return BasicMarkerFactory.class.getName(); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /logger-slf4j/src/test/java/net/openhft/chronicle/logger/slf4j/ChronicleLoggingConfigTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.slf4j; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogConfig; 21 | import org.junit.Test; 22 | 23 | import static org.junit.Assert.assertNotNull; 24 | 25 | public class ChronicleLoggingConfigTest { 26 | @Test 27 | public void testLoadClasspathIndexed() { 28 | System.setProperty("chronicle.logger.properties", "chronicle.logger.properties"); 29 | assertLoadsValidConfig(); 30 | } 31 | 32 | private void assertLoadsValidConfig() { 33 | ChronicleLogConfig config = ChronicleLogConfig.load(); 34 | assertNotNull("unable to load config", config); 35 | assertNotNull("is not a valid config", config.getAppenderConfig()); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /logger-slf4j/src/test/java/net/openhft/chronicle/logger/slf4j/Slf4jChronicleConfigurationTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.slf4j; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogConfig; 21 | import net.openhft.chronicle.logger.ChronicleLogLevel; 22 | import org.junit.Test; 23 | 24 | import java.io.File; 25 | import java.util.Properties; 26 | 27 | import static org.junit.Assert.assertEquals; 28 | import static org.junit.Assert.assertNotNull; 29 | 30 | public class Slf4jChronicleConfigurationTest extends Slf4jTestBase { 31 | 32 | @Test 33 | public void testLoadProperties() { 34 | final String cfgPath = "chronicle.logger.properties"; 35 | final ChronicleLogConfig cfg = ChronicleLogConfig.load(cfgPath); 36 | 37 | assertNotNull(cfg); 38 | 39 | assertEquals( 40 | new File(basePath("root")), 41 | new File(cfg.getString(ChronicleLogConfig.KEY_PATH))); 42 | assertEquals( 43 | ChronicleLogLevel.DEBUG.toString(), 44 | cfg.getString(ChronicleLogConfig.KEY_LEVEL).toUpperCase()); 45 | assertEquals("false", cfg.getString(ChronicleLogConfig.KEY_APPEND)); 46 | assertEquals( 47 | new File(basePath("logger_1")), 48 | new File(cfg.getString("logger_1", ChronicleLogConfig.KEY_PATH))); 49 | assertEquals( 50 | ChronicleLogLevel.INFO.toString(), 51 | cfg.getString("logger_1", ChronicleLogConfig.KEY_LEVEL).toUpperCase()); 52 | assertEquals( 53 | ChronicleLogLevel.DEBUG.toString(), 54 | cfg.getString("readwrite", ChronicleLogConfig.KEY_LEVEL).toUpperCase()); 55 | } 56 | 57 | @Test 58 | public void testLoadConfig() { 59 | final Properties properties = new Properties(); 60 | properties.setProperty("chronicle.logger.root.cfg.blockSize", "256"); 61 | 62 | final ChronicleLogConfig clc = ChronicleLogConfig.load(properties); 63 | assertNotNull(clc.getAppenderConfig()); 64 | 65 | assertEquals(256, clc.getAppenderConfig().getBlockSize()); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /logger-slf4j/src/test/java/net/openhft/chronicle/logger/slf4j/Slf4jChronicleLoggerPerfTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.slf4j; 19 | 20 | import net.openhft.chronicle.core.io.IOTools; 21 | import org.apache.commons.lang3.StringUtils; 22 | import org.junit.After; 23 | import org.junit.Before; 24 | import org.junit.Ignore; 25 | import org.junit.Test; 26 | import org.slf4j.Logger; 27 | import org.slf4j.LoggerFactory; 28 | 29 | import java.util.concurrent.ExecutorService; 30 | import java.util.concurrent.Executors; 31 | import java.util.concurrent.TimeUnit; 32 | 33 | @Ignore 34 | public class Slf4jChronicleLoggerPerfTest extends Slf4jTestBase { 35 | 36 | // ************************************************************************* 37 | // 38 | // ************************************************************************* 39 | 40 | @Before 41 | public void setUp() { 42 | System.setProperty( 43 | "chronicle.logger.properties", 44 | "chronicle.logger.perf.properties"); 45 | 46 | getChronicleLoggerFactory().reload(); 47 | } 48 | 49 | @After 50 | public void tearDown() { 51 | IOTools.deleteDirWithFiles(basePath()); 52 | } 53 | 54 | // ************************************************************************* 55 | // Single Thread 56 | // ************************************************************************* 57 | 58 | @Test 59 | public void testSingleThreadLogging1() { 60 | Thread.currentThread().setName("perf-plain"); 61 | 62 | final String testId = "perf-chronicle"; 63 | final Logger clogger = LoggerFactory.getLogger(testId); 64 | final long items = 1000000; 65 | 66 | warmup(clogger); 67 | 68 | for (int s = 64; s <= 1024; s += 64) { 69 | final String staticStr = StringUtils.leftPad("", s, 'X'); 70 | 71 | long cStart1 = System.nanoTime(); 72 | 73 | for (int i = 1; i <= items; i++) { 74 | clogger.info(staticStr); 75 | } 76 | 77 | long cEnd1 = System.nanoTime(); 78 | 79 | System.out.printf("items=%03d size=%04d => chronology=%.3f ms, chronology-average=%.3f us\n", 80 | items, 81 | staticStr.length(), 82 | (cEnd1 - cStart1) / 1e6, 83 | (cEnd1 - cStart1) / items / 1e3); 84 | } 85 | } 86 | 87 | @Test 88 | public void testSingleThreadLogging2() { 89 | Thread.currentThread().setName("perf-plain"); 90 | 91 | final String testId = "perf-chronicle"; 92 | final Logger clogger = LoggerFactory.getLogger(testId); 93 | final long items = 1000000; 94 | final String strFmt = StringUtils.leftPad("> v1={}, v2={}, v3={}", 32, 'X'); 95 | 96 | warmup(clogger); 97 | 98 | for (int n = 0; n < 10; n++) { 99 | long cStart1 = System.nanoTime(); 100 | 101 | for (int i = 1; i <= items; i++) { 102 | clogger.info(strFmt, i, i * 10, i / 16); 103 | } 104 | 105 | long cEnd1 = System.nanoTime(); 106 | 107 | System.out.printf("items=%03d => chronology=%.3f ms, chronology-average=%.3f us\n", 108 | items, 109 | (cEnd1 - cStart1) / 1e6, 110 | (cEnd1 - cStart1) / items / 1e3); 111 | } 112 | } 113 | 114 | // ************************************************************************* 115 | // Multi Thread 116 | // ************************************************************************* 117 | 118 | @Test 119 | public void testMultiThreadLogging() throws InterruptedException { 120 | warmup(LoggerFactory.getLogger("perf-chronicle")); 121 | 122 | final int RUNS = 1000000; 123 | final int THREADS = 10; 124 | 125 | for (int size : new int[]{64, 128, 256}) { 126 | { 127 | final long start = System.nanoTime(); 128 | 129 | ExecutorService es = Executors.newFixedThreadPool(THREADS); 130 | for (int t = 0; t < THREADS; t++) { 131 | es.submit(new RunnableLogger(RUNS, size, "perf-chronicle")); 132 | } 133 | 134 | es.shutdown(); 135 | es.awaitTermination(5, TimeUnit.SECONDS); 136 | 137 | final long time = System.nanoTime() - start; 138 | 139 | System.out.printf("ChronicleLog.MT (runs=%d, min size=%03d, elapsed=%.3f ms) took an average of %.3f us per entry\n", 140 | RUNS, 141 | size, 142 | time / 1e6, 143 | time / 1e3 / (RUNS * THREADS) 144 | ); 145 | } 146 | } 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /logger-slf4j/src/test/java/net/openhft/chronicle/logger/slf4j/Slf4jTestBase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.slf4j; 19 | 20 | import net.openhft.chronicle.core.OS; 21 | import net.openhft.chronicle.core.util.Time; 22 | import net.openhft.chronicle.logger.ChronicleLogLevel; 23 | import org.apache.commons.lang3.StringUtils; 24 | import org.slf4j.Logger; 25 | import org.slf4j.LoggerFactory; 26 | import org.slf4j.impl.StaticLoggerBinder; 27 | 28 | class Slf4jTestBase { 29 | 30 | // ************************************************************************* 31 | // 32 | // ************************************************************************* 33 | 34 | static final ChronicleLogLevel[] LOG_LEVELS = ChronicleLogLevel.values(); 35 | 36 | static String basePath() { 37 | String path = System.getProperty("java.io.tmpdir"); 38 | String sep = System.getProperty("file.separator"); 39 | 40 | if (!path.endsWith(sep)) { 41 | path += sep; 42 | } 43 | 44 | return path + "chronicle-slf4j"; 45 | } 46 | 47 | static String basePath(String loggerName) { 48 | return basePath() 49 | + System.getProperty("file.separator") 50 | + loggerName; 51 | } 52 | 53 | static void log(Logger logger, ChronicleLogLevel level, String fmt, Object... args) { 54 | switch (level) { 55 | case TRACE: 56 | logger.trace(fmt, args); 57 | break; 58 | 59 | case DEBUG: 60 | logger.debug(fmt, args); 61 | break; 62 | 63 | case INFO: 64 | logger.info(fmt, args); 65 | break; 66 | 67 | case WARN: 68 | logger.warn(fmt, args); 69 | break; 70 | 71 | case ERROR: 72 | logger.error(fmt, args); 73 | break; 74 | default: 75 | throw new UnsupportedOperationException(); 76 | } 77 | } 78 | 79 | static void warmup(Logger logger) { 80 | for (int i = 0; i < 10; i++) { 81 | logger.info("warmup"); 82 | } 83 | } 84 | 85 | // ************************************************************************* 86 | // 87 | // ************************************************************************* 88 | 89 | /** 90 | * @return the ChronicleLoggerFactory singleton 91 | */ 92 | ChronicleLoggerFactory getChronicleLoggerFactory() { 93 | return (ChronicleLoggerFactory) StaticLoggerBinder.getSingleton().getLoggerFactory(); 94 | } 95 | 96 | // ************************************************************************* 97 | // 98 | // ************************************************************************* 99 | 100 | protected final class RunnableLogger implements Runnable { 101 | private final Logger logger; 102 | private final int runs; 103 | private final String fmt; 104 | private final String fmtBase = " > val1={}, val2={}, val3={}"; 105 | 106 | public RunnableLogger(int runs, int pad, String loggerName) { 107 | this.logger = LoggerFactory.getLogger(loggerName); 108 | this.runs = runs; 109 | this.fmt = StringUtils.rightPad(fmtBase, pad + fmtBase.length() - (4 + 8 + 8), "X"); 110 | } 111 | 112 | @Override 113 | public void run() { 114 | for (int i = 0; i < this.runs; i++) { 115 | this.logger.info(fmt, i, i * 7L, i / 16.0); 116 | } 117 | } 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /logger-slf4j/src/test/resources/chronicle.logger.perf.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2014-2017 Chronicle Software 3 | # 4 | # https://chronicle.software 5 | # 6 | # This program is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License 16 | # along with this program. If not, see . 17 | # 18 | 19 | chronicle.logger.base = ${java.io.tmpdir}/chronicle-slf4j 20 | 21 | chronicle.logger.root.path = ${chronicle.logger.base}/perf 22 | chronicle.logger.root.level = debug 23 | chronicle.logger.root.append = false 24 | -------------------------------------------------------------------------------- /logger-slf4j/src/test/resources/chronicle.logger.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2014-2017 Chronicle Software 3 | # 4 | # https://chronicle.software 5 | # 6 | # This program is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License 16 | # along with this program. If not, see . 17 | # 18 | 19 | ################################################################################ 20 | # Common 21 | ################################################################################ 22 | 23 | chronicle.logger.base = ${java.io.tmpdir}/chronicle-slf4j 24 | chronicle.logger.root.path = ${chronicle.logger.base}/root 25 | chronicle.logger.root.level = debug 26 | chronicle.logger.root.append = false 27 | 28 | ################################################################################ 29 | # Loggers 30 | ################################################################################ 31 | 32 | # logger : Logger1 33 | chronicle.logger.logger_1.path = ${chronicle.logger.base}/logger_1 34 | chronicle.logger.logger_1.level = info 35 | 36 | # logger : impl 37 | chronicle.logger.readwrite.path = ${chronicle.logger.base}/readwrite 38 | -------------------------------------------------------------------------------- /logger-tools/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 22 | 23 | 4.0.0 24 | 25 | 26 | net.openhft 27 | chronicle-logger 28 | 4.27ea2-SNAPSHOT 29 | ../pom.xml 30 | 31 | 32 | OpenHFT/Chronicle-Logger/logger-tools 33 | chronicle-logger-tools 34 | bundle 35 | 36 | 37 | 38 | net.openhft 39 | chronicle-logger-core 40 | 41 | 42 | 43 | net.openhft 44 | chronicle-wire 45 | 46 | 47 | 48 | 49 | org.slf4j 50 | slf4j-api 51 | 52 | 53 | 54 | 55 | net.openhft 56 | chronicle-logger-logback 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | org.apache.maven.plugins 65 | maven-surefire-plugin 66 | 67 | 1 68 | false 69 | 70 | **/*PerfTest.java 71 | 72 | 73 | ${project.build.directory} 74 | 75 | 76 | 77 | 85 | 86 | org.apache.servicemix.tooling 87 | depends-maven-plugin 88 | 89 | 90 | generate-depends-file 91 | 92 | generate-depends-file 93 | 94 | 95 | 96 | 97 | 98 | org.apache.felix 99 | maven-bundle-plugin 100 | true 101 | 102 | 103 | ${project.groupId}.${project.artifactId} 104 | OpenHFT :: ${project.artifactId} 105 | ${project.version} 106 | net.openhft.chronicle.logger.tools.* 107 | 108 | 109 | 110 | 114 | 115 | 116 | manifest 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 126 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 127 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 128 | master 129 | 130 | 131 | 132 | -------------------------------------------------------------------------------- /logger-tools/src/main/java/net/openhft/chronicle/logger/tools/ChroniCat.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.tools; 19 | 20 | import net.openhft.chronicle.wire.WireType; 21 | 22 | public final class ChroniCat { 23 | 24 | private ChroniCat() { 25 | } 26 | 27 | public static void main(String[] args) { 28 | try { 29 | 30 | if (args.length >= 1) { 31 | int i = 0; 32 | final WireType wt; 33 | if ("-w".equals(args[i])) { 34 | wt = WireType.valueOf(args[++i].trim().toUpperCase()); 35 | i++; 36 | } else { 37 | wt = WireType.BINARY_LIGHT; 38 | } 39 | 40 | ChronicleLogReader reader = new ChronicleLogReader(args[i].trim(), wt); 41 | 42 | reader.processLogs(ChronicleLogReader::printf, false); 43 | 44 | } else { 45 | System.err.println("\nUsage: ChroniCat [-w ] "); 46 | System.err.println(" - wire format, default BINARY_LIGHT"); 47 | System.err.println(" - base path of Chronicle Logs storage"); 48 | } 49 | } catch (Exception e) { 50 | e.printStackTrace(System.err); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /logger-tools/src/main/java/net/openhft/chronicle/logger/tools/ChroniTail.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.tools; 19 | 20 | import net.openhft.chronicle.wire.WireType; 21 | 22 | public final class ChroniTail { 23 | 24 | private ChroniTail() { 25 | } 26 | 27 | public static void main(String[] args) { 28 | try { 29 | 30 | if (args.length >= 1) { 31 | int i = 0; 32 | final WireType wt; 33 | if ("-w".equals(args[i++])) { 34 | wt = WireType.valueOf(args[i++].trim().toUpperCase()); 35 | } else { 36 | wt = WireType.BINARY_LIGHT; 37 | } 38 | 39 | ChronicleLogReader reader = new ChronicleLogReader(args[i].trim(), wt); 40 | 41 | reader.processLogs(ChronicleLogReader::printf, true); 42 | 43 | } else { 44 | System.err.println("\nUsage: ChroniTail [-w ] "); 45 | System.err.println(" - wire format, default BINARY_LIGHT"); 46 | System.err.println(" - base path of Chronicle Logs storage"); 47 | } 48 | } catch (Exception e) { 49 | e.printStackTrace(System.err); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /logger-tools/src/main/java/net/openhft/chronicle/logger/tools/ChronicleLogProcessor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.tools; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogLevel; 21 | import org.jetbrains.annotations.Nullable; 22 | 23 | public interface ChronicleLogProcessor { 24 | void process( 25 | final long timestamp, 26 | final ChronicleLogLevel level, 27 | final String loggerName, 28 | final String threadName, 29 | final String message, 30 | @Nullable final Throwable throwable, 31 | final Object[] args); 32 | } 33 | -------------------------------------------------------------------------------- /logger-tools/src/main/java/net/openhft/chronicle/logger/tools/ChronicleLogReader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2022 Chronicle Software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.tools; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogLevel; 21 | import net.openhft.chronicle.queue.ChronicleQueue; 22 | import net.openhft.chronicle.queue.ExcerptTailer; 23 | import net.openhft.chronicle.wire.DocumentContext; 24 | import net.openhft.chronicle.wire.Wire; 25 | import net.openhft.chronicle.wire.WireType; 26 | import org.jetbrains.annotations.NotNull; 27 | import org.jetbrains.annotations.Nullable; 28 | import org.slf4j.helpers.MessageFormatter; 29 | 30 | import java.text.SimpleDateFormat; 31 | import java.util.ArrayList; 32 | import java.util.List; 33 | 34 | /** 35 | * Generic tool allowing users to process Chronicle logs in their own way 36 | */ 37 | public class ChronicleLogReader { 38 | private static final SimpleDateFormat tsFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); 39 | private final ChronicleQueue cq; 40 | 41 | /** 42 | * Create reader with default wire type 43 | * 44 | * @param path the path to Chronicle Logs storage 45 | */ 46 | public ChronicleLogReader( 47 | @NotNull String path) { 48 | this(path, WireType.BINARY_LIGHT); 49 | } 50 | 51 | /** 52 | * @param path the path to Chronicle Logs storage 53 | * @param wireType Chronicle wire type. Must match the wire type specified in corresponding Chronicle Logger 54 | */ 55 | public ChronicleLogReader( 56 | @NotNull String path, 57 | @NotNull WireType wireType) { 58 | cq = ChronicleQueue.singleBuilder(path).wireType(wireType).build(); 59 | } 60 | 61 | /** 62 | * Simple {@link ChronicleLogProcessor} implementation. Prints formatted message to stdout 63 | */ 64 | public static void printf( 65 | long timestamp, 66 | ChronicleLogLevel level, 67 | String loggerName, 68 | String threadName, 69 | String message, 70 | @Nullable Throwable throwable, 71 | Object[] args) { 72 | 73 | message = MessageFormatter.arrayFormat(message, args).getMessage(); 74 | 75 | if (throwable == null) { 76 | System.out.printf("%s [%s] [%s] [%s] %s%n", 77 | tsFormat.format(timestamp), 78 | level.toString(), 79 | threadName, 80 | loggerName, 81 | message); 82 | 83 | } else { 84 | System.out.printf("%s [%s] [%s] [%s] %s%n%s%n", 85 | tsFormat.format(timestamp), 86 | level.toString(), 87 | threadName, 88 | loggerName, 89 | message, 90 | throwable.toString()); 91 | } 92 | } 93 | 94 | /** 95 | * Decode logs 96 | * 97 | * @param processor user-provided processor called for each log message 98 | * @param waitForIt whether to wait for more data or stop after EOF reached 99 | */ 100 | public void processLogs(@NotNull ChronicleLogProcessor processor, boolean waitForIt) { 101 | ExcerptTailer tailer = cq.createTailer(); 102 | for (; ; ) { 103 | try (DocumentContext dc = tailer.readingDocument()) { 104 | Wire wire = dc.wire(); 105 | if (wire == null) 106 | if (waitForIt) { 107 | try { 108 | Thread.sleep(50L); 109 | } catch (InterruptedException ignored) { 110 | 111 | } 112 | continue; 113 | } else { 114 | break; 115 | } 116 | 117 | long timestamp = wire.read("ts").int64(); 118 | ChronicleLogLevel level = wire.read("level").asEnum(ChronicleLogLevel.class); 119 | String threadName = wire.read("threadName").text(); 120 | String loggerName = wire.read("loggerName").text(); 121 | String message = wire.read("message").text(); 122 | Throwable th = wire.hasMore() ? wire.read("throwable").throwable(false) : null; 123 | List argsL = new ArrayList<>(); 124 | if (wire.hasMore()) { 125 | wire.read("args").sequence(argsL, (l, vi) -> { 126 | while (vi.hasNextSequenceItem()) { 127 | l.add(vi.object(Object.class)); 128 | } 129 | }); 130 | } 131 | Object[] args = argsL.toArray(new Object[argsL.size()]); 132 | processor.process(timestamp, level, threadName, loggerName, message, th, args); 133 | } 134 | } 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /logger-tools/src/main/java/net/openhft/chronicle/logger/tools/internal/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This package and any and all sub-packages contains strictly internal classes for this Chronicle library. 3 | * Internal classes shall never be used directly. 4 | * 5 | * Specifically, the following actions (including, but not limited to) are not allowed 6 | * on internal classes and packages: 7 | * 8 | * Casting to 9 | * Reflection of any kind 10 | * Explicit Serialize/deserialize 11 | * 12 | * 13 | * The classes in this package and any sub-package are subject to 14 | * changes at any time for any reason. 15 | */ 16 | package net.openhft.chronicle.logger.tools.internal; 17 | -------------------------------------------------------------------------------- /logger-tools/src/test/java/net/openhft/chronicle/logger/tools/ChronicleLogReaderTest.java: -------------------------------------------------------------------------------- 1 | package net.openhft.chronicle.logger.tools; 2 | 3 | import net.openhft.chronicle.core.OS; 4 | import net.openhft.chronicle.core.util.Time; 5 | import net.openhft.chronicle.wire.WireType; 6 | import org.junit.Before; 7 | import org.junit.Test; 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | 11 | public class ChronicleLogReaderTest { 12 | @Before 13 | public void setup() { 14 | System.setProperty( 15 | "logback.configurationFile", 16 | System.getProperty("resources.path") 17 | + "/logback-chronicle-binary-appender.xml"); 18 | } 19 | 20 | @Test 21 | public void readTest() { 22 | final Logger logger = LoggerFactory.getLogger("binary-chronicle"); 23 | logger.info("test {} {} {}", 1, 100L, 100.123D); 24 | logger.info("test {} {} {}", 2, 100L, 100.123D); 25 | logger.info("test {} {} {}", 3, 100L, 100.123D); 26 | 27 | ChronicleLogReader reader = new ChronicleLogReader(OS.getTarget() + "/chronicle-logback/binary-chronicle" + Time.uniqueId(), WireType.BINARY_LIGHT); 28 | reader.processLogs(ChronicleLogReader::printf, false); 29 | 30 | //ChroniCat.main(new String[] {OS.getTarget() + "/chronicle-logback/binary-chronicle"}); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /logger-tools/src/test/resources/logback-chronicle-binary-appender.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 22 | 23 | 25 | 26 | %d %contextName [%t] %level %logger{36} - %msg%n 27 | 28 | 29 | 31 | ${java.io.tmpdir}/chronicle-logback/binary-chronicle 32 | false 33 | false 34 | 35 | 128 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 4.0.0 22 | 23 | 24 | net.openhft 25 | java-parent-pom 26 | 1.27ea1 27 | 28 | 29 | 30 | chronicle-logger 31 | 4.27ea2-SNAPSHOT 32 | pom 33 | 34 | OpenHFT/Chronicle-Logger 35 | OpenHFT :: High Performance Logging 36 | 37 | 38 | 39 | 40 | net.openhft 41 | third-party-bom 42 | 3.27ea2 43 | pom 44 | import 45 | 46 | 47 | 48 | net.openhft 49 | chronicle-bom 50 | 2.27ea-SNAPSHOT 51 | pom 52 | import 53 | 54 | 55 | 56 | 57 | net.openhft 58 | chronicle-logger-core 59 | ${project.version} 60 | 61 | 62 | 63 | net.openhft 64 | chronicle-logger-logback 65 | ${project.version} 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | net.openhft 75 | chronicle-core 76 | 77 | 78 | 79 | net.openhft 80 | chronicle-bytes 81 | 82 | 83 | 84 | net.openhft 85 | chronicle-queue 86 | 87 | 88 | 89 | org.jetbrains 90 | annotations 91 | 92 | 93 | 94 | 95 | org.apache.commons 96 | commons-lang3 97 | test 98 | 99 | 100 | junit 101 | junit 102 | test 103 | 104 | 105 | 106 | 107 | org.openjdk.jmh 108 | jmh-core 109 | test 110 | 111 | 112 | org.openjdk.jmh 113 | jmh-core-benchmarks 114 | test 115 | 116 | 117 | 118 | 119 | logger-core 120 | logger-jul 121 | logger-jcl 122 | logger-slf4j 123 | logger-slf4j-2 124 | logger-logback 125 | logger-log4j-1 126 | logger-log4j-2 127 | logger-tools 128 | benchmark 129 | 130 | 131 | 132 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 133 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 134 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 135 | master 136 | 137 | 138 | 139 | 140 | --------------------------------------------------------------------------------
13 | * The classes in this package and any sub-package are subject to 14 | * changes at any time for any reason. 15 | */ 16 | package net.openhft.chronicle.logger.jul.internal; 17 | -------------------------------------------------------------------------------- /logger-jul/src/test/java/net/openhft/chronicle/logger/jul/JulHandlerTestBase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.jul; 19 | 20 | import net.openhft.chronicle.core.OS; 21 | import net.openhft.chronicle.core.util.Time; 22 | 23 | import java.io.File; 24 | import java.io.FileInputStream; 25 | import java.io.IOException; 26 | import java.util.logging.LogManager; 27 | 28 | import static org.junit.Assert.assertNotNull; 29 | import static org.junit.Assert.assertTrue; 30 | 31 | public class JulHandlerTestBase extends JulTestBase { 32 | 33 | // ************************************************************************* 34 | // 35 | // ************************************************************************* 36 | 37 | protected static String rootPath() { 38 | String path = System.getProperty("java.io.tmpdir"); 39 | String sep = System.getProperty("file.separator"); 40 | 41 | if (!path.endsWith(sep)) { 42 | path += sep; 43 | } 44 | 45 | return path + "chronicle-jul"; 46 | } 47 | 48 | protected static String basePath(String type) { 49 | return rootPath() 50 | + System.getProperty("file.separator") 51 | + type; 52 | } 53 | 54 | /** 55 | * @param id the id of the logger 56 | * @throws IOException if an I/O error occurs 57 | */ 58 | protected void setupLogManager(String id) throws IOException { 59 | String cfgPath = System.getProperty("resources.path"); 60 | File cfgFile = new File(cfgPath, id + ".properties"); 61 | 62 | assertNotNull(cfgPath); 63 | assertTrue(cfgFile.exists()); 64 | 65 | LogManager manager = LogManager.getLogManager(); 66 | manager.reset(); 67 | manager.readConfiguration(new FileInputStream(cfgFile)); 68 | } 69 | 70 | // ************************************************************************* 71 | // 72 | // ************************************************************************* 73 | 74 | } 75 | -------------------------------------------------------------------------------- /logger-jul/src/test/java/net/openhft/chronicle/logger/jul/JulLoggerTestBase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.jul; 19 | 20 | import net.openhft.chronicle.core.OS; 21 | import net.openhft.chronicle.core.util.Time; 22 | 23 | import java.util.logging.LogManager; 24 | 25 | class JulLoggerTestBase extends JulTestBase { 26 | 27 | // ************************************************************************* 28 | // 29 | // ************************************************************************* 30 | 31 | static String basePath() { 32 | String path = System.getProperty("java.io.tmpdir"); 33 | String sep = System.getProperty("file.separator"); 34 | 35 | if (!path.endsWith(sep)) { 36 | path += sep; 37 | } 38 | 39 | return path + "chronicle-jul-api"; 40 | } 41 | 42 | static String basePath(String loggerName) { 43 | return basePath() 44 | + System.getProperty("file.separator") 45 | + loggerName; 46 | } 47 | 48 | // ************************************************************************* 49 | // 50 | // ************************************************************************* 51 | 52 | static void setupLogger(Class> testName) { 53 | setupLogger(testName.getSimpleName()); 54 | } 55 | 56 | static void setupLogger(String id) { 57 | System.setProperty( 58 | "java.util.logging.manager", 59 | ChronicleLoggerManager.class.getName()); 60 | System.setProperty( 61 | "sun.util.logging.disableCallerCheck", 62 | "false"); 63 | System.setProperty( 64 | "chronicle.logger.properties", 65 | id.endsWith(".properties") ? id : id + ".properties"); 66 | 67 | LogManager.getLogManager().reset(); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /logger-jul/src/test/java/net/openhft/chronicle/logger/jul/JulTestBase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.jul; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogLevel; 21 | 22 | import java.util.logging.Level; 23 | import java.util.logging.Logger; 24 | 25 | public class JulTestBase { 26 | 27 | protected static final ChronicleLogLevel[] LOG_LEVELS = ChronicleLogLevel.values(); 28 | 29 | // ************************************************************************* 30 | // 31 | // ************************************************************************* 32 | 33 | protected static void log(Logger logger, ChronicleLogLevel level, String fmt, Object... args) { 34 | switch (level) { 35 | case TRACE: 36 | logger.log(Level.FINER, fmt, args); 37 | break; 38 | 39 | case DEBUG: 40 | logger.log(Level.FINE, fmt, args); 41 | break; 42 | 43 | case INFO: 44 | logger.log(Level.INFO, fmt, args); 45 | break; 46 | 47 | case WARN: 48 | logger.log(Level.WARNING, fmt, args); 49 | break; 50 | 51 | case ERROR: 52 | logger.log(Level.SEVERE, fmt, args); 53 | break; 54 | default: 55 | throw new UnsupportedOperationException(); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /logger-jul/src/test/resources/JulLoggerChronicleTest.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2014-2017 Chronicle Software 3 | # 4 | # https://chronicle.software 5 | # 6 | # This program is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License 16 | # along with this program. If not, see . 17 | # 18 | 19 | ################################################################################ 20 | # Common 21 | ################################################################################ 22 | 23 | chronicle.logger.base = ${java.io.tmpdir}/chronicle-jul-api 24 | 25 | chronicle.logger.root.path = ${chronicle.logger.base}/root-binary 26 | chronicle.logger.root.level = debug 27 | chronicle.logger.root.append = false 28 | 29 | chronicle.logger.logger_1.path = ${chronicle.logger.base}/logger_1 30 | chronicle.logger.logger_1.level = info 31 | chronicle.logger.logger_1.wireType = json 32 | 33 | chronicle.logger.logger_bin.path = ${chronicle.logger.base}/logger_bin 34 | chronicle.logger.logger_bin.level = trace 35 | -------------------------------------------------------------------------------- /logger-jul/src/test/resources/binary-cfg.properties: -------------------------------------------------------------------------------- 1 | 2 | # 3 | # Copyright (C) 2014-2017 Chronicle Software 4 | # 5 | # https://chronicle.software 6 | # 7 | # This program is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU Lesser General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License. 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 14 | # GNU 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, see . 18 | # 19 | 20 | handlers=java.util.logging.ConsoleHandler, net.openhft.chronicle.logger.jul.ChronicleHandler 21 | 22 | .level=ALL 23 | 24 | java.util.logging.ConsoleHandler.level=ALL 25 | java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter 26 | 27 | net.openhft.level=WARNING 28 | net.openhft.handlers=java.util.logging.ConsoleHandler 29 | 30 | ################################################################################ 31 | # BINARY 32 | ################################################################################ 33 | 34 | net.openhft.chronicle.logger.jul.ChronicleHandler.path = ${java.io.tmpdir}/chronicle-jul 35 | net.openhft.chronicle.logger.jul.ChronicleHandler.level = ALL 36 | 37 | binary-cfg.level=INFO 38 | binary-cfg.handlers=net.openhft.chronicle.logger.jul.ChronicleHandler 39 | binary-cfg.useParentHandlers=false 40 | -------------------------------------------------------------------------------- /logger-jul/src/test/resources/binary-chronicle.properties: -------------------------------------------------------------------------------- 1 | 2 | # 3 | # Copyright (C) 2014-2017 Chronicle Software 4 | # 5 | # https://chronicle.software 6 | # 7 | # This program is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU Lesser General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License. 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 14 | # GNU 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, see . 18 | # 19 | 20 | handlers=java.util.logging.ConsoleHandler, net.openhft.chronicle.logger.jul.ChronicleHandler 21 | 22 | .level=ALL 23 | 24 | java.util.logging.ConsoleHandler.level=ALL 25 | java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter 26 | 27 | net.openhft.level=WARNING 28 | net.openhft.handlers=java.util.logging.ConsoleHandler 29 | 30 | ################################################################################ 31 | # BINARY 32 | ################################################################################ 33 | 34 | net.openhft.chronicle.logger.jul.ChronicleHandler.path = ${java.io.tmpdir}/chronicle-jul/binary-chronicle 35 | net.openhft.chronicle.logger.jul.ChronicleHandler.level = ALL 36 | 37 | binary-chronicle.level=ALL 38 | binary-chronicle.handlers=net.openhft.chronicle.logger.jul.ChronicleHandler 39 | binary-chronicle.useParentHandlers=false 40 | 41 | -------------------------------------------------------------------------------- /logger-log4j-1/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 22 | 23 | 4.0.0 24 | 25 | 26 | net.openhft 27 | chronicle-logger 28 | 4.27ea2-SNAPSHOT 29 | ../pom.xml 30 | 31 | 32 | OpenHFT/Chronicle-Logger/logger-log4j-1 33 | chronicle-logger-log4j-1 34 | bundle 35 | 36 | 37 | 38 | net.openhft 39 | chronicle-logger-core 40 | 41 | 42 | 43 | 44 | org.slf4j 45 | slf4j-api 46 | 47 | 48 | org.slf4j 49 | slf4j-log4j12 50 | 1.7.33 51 | 52 | 53 | 54 | 55 | log4j 56 | log4j 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | org.apache.maven.plugins 65 | maven-surefire-plugin 66 | 67 | 1 68 | false 69 | 70 | **/*PerfTest.java 71 | 72 | 73 | ${project.build.directory} 74 | 75 | 76 | 77 | 85 | 86 | org.apache.servicemix.tooling 87 | depends-maven-plugin 88 | 89 | 90 | generate-depends-file 91 | 92 | generate-depends-file 93 | 94 | 95 | 96 | 97 | 98 | org.apache.felix 99 | maven-bundle-plugin 100 | true 101 | 102 | 103 | ${project.groupId}.${project.artifactId} 104 | OpenHFT :: ${project.artifactId} 105 | ${project.version} 106 | net.openhft.chronicle.logger.log4j1.* 107 | 108 | 109 | 110 | 114 | 115 | 116 | manifest 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 126 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 127 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 128 | master 129 | 130 | 131 | 132 | -------------------------------------------------------------------------------- /logger-log4j-1/src/main/java/net/openhft/chronicle/logger/log4j1/ChronicleAppender.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.log4j1; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogWriter; 21 | import net.openhft.chronicle.logger.DefaultChronicleLogWriter; 22 | import net.openhft.chronicle.logger.LogAppenderConfig; 23 | 24 | import java.io.IOException; 25 | 26 | public final class ChronicleAppender extends AbstractChronicleAppender { 27 | 28 | private final LogAppenderConfig config; 29 | 30 | public ChronicleAppender() { 31 | this.config = new LogAppenderConfig(); 32 | } 33 | 34 | // ************************************************************************* 35 | // Custom logging options 36 | // ************************************************************************* 37 | 38 | public void setBlockSize(int blockSize) { 39 | config.setBlockSize(blockSize); 40 | } 41 | 42 | public void setBufferCapacity(int bufferCapacity) { 43 | config.setBufferCapacity(bufferCapacity); 44 | } 45 | 46 | public String rollCycle() { 47 | return config.getRollCycle(); 48 | } 49 | 50 | public void rollCycle(String rollCycle) { 51 | config.setRollCycle(rollCycle); 52 | } 53 | 54 | @Override 55 | protected ChronicleLogWriter createWriter() throws IOException { 56 | return new DefaultChronicleLogWriter(this.config.build(this.getPath(), this.getWireType())); 57 | } 58 | 59 | // ************************************************************************* 60 | // LogAppenderConfig 61 | // ************************************************************************* 62 | 63 | LogAppenderConfig getChronicleConfig() { 64 | return this.config; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /logger-log4j-1/src/main/java/net/openhft/chronicle/logger/log4j1/internal/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This package and any and all sub-packages contains strictly internal classes for this Chronicle library. 3 | * Internal classes shall never be used directly. 4 | *
13 | * The classes in this package and any sub-package are subject to 14 | * changes at any time for any reason. 15 | */ 16 | package net.openhft.chronicle.logger.log4j1.internal; 17 | -------------------------------------------------------------------------------- /logger-log4j-1/src/test/java/net/openhft/chronicle/logger/log4j1/Log4j1TestBase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.log4j1; 19 | 20 | import net.openhft.chronicle.core.OS; 21 | import net.openhft.chronicle.core.util.Time; 22 | import net.openhft.chronicle.logger.ChronicleLogLevel; 23 | import org.slf4j.Logger; 24 | 25 | import java.io.File; 26 | 27 | class Log4j1TestBase { 28 | 29 | // ************************************************************************* 30 | // 31 | // ************************************************************************* 32 | 33 | static final ChronicleLogLevel[] LOG_LEVELS = ChronicleLogLevel.values(); 34 | 35 | static String rootPath() { 36 | String path = System.getProperty("java.io.tmpdir"); 37 | String sep = System.getProperty("file.separator"); 38 | 39 | if (!path.endsWith(sep)) { 40 | path += sep; 41 | } 42 | 43 | return path + "chronicle-log4j1"; 44 | } 45 | 46 | static String basePath(String type) { 47 | return rootPath() 48 | + File.separator 49 | + type; 50 | } 51 | 52 | static void log(Logger logger, ChronicleLogLevel level, String fmt, Object... args) { 53 | switch (level) { 54 | case TRACE: 55 | logger.trace(fmt, args); 56 | break; 57 | 58 | case DEBUG: 59 | logger.debug(fmt, args); 60 | break; 61 | 62 | case INFO: 63 | logger.info(fmt, args); 64 | break; 65 | 66 | case WARN: 67 | logger.warn(fmt, args); 68 | break; 69 | 70 | case ERROR: 71 | logger.error(fmt, args); 72 | break; 73 | default: 74 | throw new UnsupportedOperationException(); 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /logger-log4j-1/src/test/resources/log4j.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /logger-log4j-2/src/main/java/net/openhft/chronicle/logger/log4j2/ChronicleAppender.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.log4j2; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogWriter; 21 | import net.openhft.chronicle.logger.DefaultChronicleLogWriter; 22 | import net.openhft.chronicle.logger.LogAppenderConfig; 23 | import org.apache.logging.log4j.core.Filter; 24 | import org.apache.logging.log4j.core.LogEvent; 25 | import org.apache.logging.log4j.core.config.plugins.Plugin; 26 | import org.apache.logging.log4j.core.config.plugins.PluginAttribute; 27 | import org.apache.logging.log4j.core.config.plugins.PluginElement; 28 | import org.apache.logging.log4j.core.config.plugins.PluginFactory; 29 | import org.jetbrains.annotations.NotNull; 30 | 31 | import java.io.IOException; 32 | 33 | @Plugin( 34 | name = "Chronicle", 35 | category = "Core", 36 | elementType = "appender", 37 | printObject = true) 38 | public class ChronicleAppender extends AbstractChronicleAppender { 39 | 40 | private final ChronicleCfg config; 41 | 42 | public ChronicleAppender(final String name, final Filter filter, final String path, final String wireType, final ChronicleCfg config) { 43 | super(name, filter, path, wireType); 44 | 45 | this.config = config != null ? config : new ChronicleCfg(); 46 | } 47 | 48 | // ************************************************************************* 49 | // 50 | // ************************************************************************* 51 | 52 | @PluginFactory 53 | public static ChronicleAppender createAppender( 54 | @PluginAttribute("name") final String name, 55 | @PluginAttribute("path") final String path, 56 | @PluginAttribute("wireType") final String wireType, 57 | @PluginElement("chronicleCfg") final ChronicleCfg chronicleConfig, 58 | @PluginElement("filter") final Filter filter) { 59 | if (name == null) { 60 | LOGGER.error("No name provided for ChronicleAppender"); 61 | return null; 62 | } 63 | 64 | if (path == null) { 65 | LOGGER.error("No path provided for ChronicleAppender"); 66 | return null; 67 | } 68 | 69 | return new ChronicleAppender(name, filter, path, wireType, chronicleConfig); 70 | } 71 | 72 | @Override 73 | public void doAppend(@NotNull final LogEvent event, @NotNull final ChronicleLogWriter writer) { 74 | writer.write( 75 | toChronicleLogLevel(event.getLevel()), 76 | event.getTimeMillis(), 77 | event.getThreadName(), 78 | event.getLoggerName(), 79 | event.getMessage().getFormattedMessage(), 80 | event.getThrown() 81 | ); 82 | } 83 | 84 | @Override 85 | protected ChronicleLogWriter createWriter() throws IOException { 86 | return new DefaultChronicleLogWriter(config.build(getPath(), getWireType())); 87 | } 88 | 89 | // ************************************************************************* 90 | // 91 | // ************************************************************************* 92 | 93 | protected LogAppenderConfig getChronicleConfig() { 94 | return this.config; 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /logger-log4j-2/src/main/java/net/openhft/chronicle/logger/log4j2/internal/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This package and any and all sub-packages contains strictly internal classes for this Chronicle library. 3 | * Internal classes shall never be used directly. 4 | *
13 | * The classes in this package and any sub-package are subject to 14 | * changes at any time for any reason. 15 | */ 16 | package net.openhft.chronicle.logger.log4j2.internal; 17 | -------------------------------------------------------------------------------- /logger-log4j-2/src/test/java/net/openhft/chronicle/logger/log4j2/Log4j2TestBase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.log4j2; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogLevel; 21 | import org.apache.logging.log4j.LogManager; 22 | import org.slf4j.Logger; 23 | 24 | import java.io.File; 25 | 26 | public class Log4j2TestBase { 27 | 28 | // ************************************************************************* 29 | // 30 | // ************************************************************************* 31 | 32 | static final ChronicleLogLevel[] LOG_LEVELS = ChronicleLogLevel.values(); 33 | 34 | static String rootPath() { 35 | String path = System.getProperty("java.io.tmpdir"); 36 | String sep = System.getProperty("file.separator"); 37 | 38 | if (!path.endsWith(sep)) { 39 | path += sep; 40 | } 41 | 42 | return path + "chronicle-log4j2"; 43 | } 44 | 45 | static String basePath(String type) { 46 | return rootPath() 47 | + File.separator 48 | + type; 49 | } 50 | 51 | static void log(Logger logger, ChronicleLogLevel level, String fmt, Object... args) { 52 | switch (level) { 53 | case TRACE: 54 | logger.trace(fmt, args); 55 | break; 56 | 57 | case DEBUG: 58 | logger.debug(fmt, args); 59 | break; 60 | 61 | case INFO: 62 | logger.info(fmt, args); 63 | break; 64 | 65 | case WARN: 66 | logger.warn(fmt, args); 67 | break; 68 | 69 | case ERROR: 70 | logger.error(fmt, args); 71 | break; 72 | default: 73 | throw new UnsupportedOperationException(); 74 | } 75 | } 76 | 77 | // ************************************************************************* 78 | // 79 | // ************************************************************************* 80 | 81 | static org.apache.logging.log4j.core.Appender getAppender(String name) { 82 | final org.apache.logging.log4j.core.LoggerContext ctx = 83 | (org.apache.logging.log4j.core.LoggerContext) LogManager.getContext(); 84 | 85 | return ctx.getConfiguration().getAppender(name); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /logger-log4j-2/src/test/java/net/openhft/chronicle/logger/log4j2/Log4j2VulnerabilityTest.java: -------------------------------------------------------------------------------- 1 | package net.openhft.chronicle.logger.log4j2; 2 | 3 | import org.apache.logging.log4j.LogManager; 4 | import org.junit.BeforeClass; 5 | import org.junit.Test; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | 9 | import java.io.IOException; 10 | import java.nio.file.Files; 11 | import java.nio.file.Paths; 12 | 13 | /** 14 | * see https://blog.cloudflare.com/inside-the-log4j2-vulnerability-cve-2021-44228/ etc. 15 | *
16 | * This is not a proper unit test - just some exploratory code 17 | */ 18 | public class Log4j2VulnerabilityTest extends Log4j2TestBase { 19 | 20 | public static final String VULNERABILITY = "${jndi:ldap://localhost/xxxx}"; 21 | 22 | @BeforeClass 23 | public static void systemProperties() { 24 | System.setProperty("com.sun.jndi.rmi.object.trustURLCodebase", "true"); 25 | } 26 | 27 | /** 28 | * Run this test with -Dlog4j2.debug and you will not see any JNDI-related logging - see below 29 | */ 30 | @Test 31 | public void testVulnerability() throws IOException { 32 | final String testId = "chronicle"; 33 | final String threadId = testId + "-th"; 34 | final Logger logger = LoggerFactory.getLogger(testId); 35 | 36 | Thread.currentThread().setName(threadId); 37 | Files.createDirectories(Paths.get(basePath(testId))); 38 | 39 | logger.error(VULNERABILITY); 40 | } 41 | 42 | /** 43 | * Run this test with -Dlog4j2.debug and you will see 44 | *
45 | * {@code WARN StatusLogger Error looking up JNDI resource [ldap://localhost/xxxx]} 46 | *
13 | * The classes in this package and any sub-package are subject to 14 | * changes at any time for any reason. 15 | */ 16 | package net.openhft.chronicle.logger.logback.internal; 17 | -------------------------------------------------------------------------------- /logger-logback/src/test/java/net/openhft/chronicle/logger/logback/LogbackChronicleProgrammaticConfigTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.logback; 19 | 20 | import ch.qos.logback.classic.Logger; 21 | import ch.qos.logback.classic.LoggerContext; 22 | import net.openhft.chronicle.core.OS; 23 | import net.openhft.chronicle.core.util.Time; 24 | import net.openhft.chronicle.logger.LogAppenderConfig; 25 | import org.junit.Test; 26 | import org.slf4j.LoggerFactory; 27 | 28 | public class LogbackChronicleProgrammaticConfigTest extends LogbackTestBase { 29 | 30 | @Test 31 | public void testConfig() { 32 | LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory(); 33 | context.reset(); 34 | 35 | ChronicleAppender appender = new ChronicleAppender(); 36 | appender.setPath(OS.getTarget() + "/clog" + Time.uniqueId()); 37 | appender.setChronicleConfig(new LogAppenderConfig()); 38 | appender.setContext(context); 39 | appender.start(); 40 | 41 | Logger logger = context.getLogger(Logger.ROOT_LOGGER_NAME); 42 | logger.addAppender(appender); 43 | 44 | logger.info("Hello World"); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /logger-logback/src/test/java/net/openhft/chronicle/logger/logback/LogbackIndexedChronicleConfigTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.logback; 19 | 20 | import ch.qos.logback.classic.spi.ILoggingEvent; 21 | import org.junit.Before; 22 | import org.junit.Test; 23 | 24 | import java.io.IOException; 25 | 26 | import static org.junit.Assert.*; 27 | 28 | public class LogbackIndexedChronicleConfigTest extends LogbackTestBase { 29 | 30 | @Before 31 | public void setup() { 32 | System.setProperty( 33 | "logback.configurationFile", 34 | System.getProperty("resources.path") + "/logback-chronicle-config.xml" 35 | ); 36 | } 37 | 38 | // ************************************************************************* 39 | // 40 | // ************************************************************************* 41 | 42 | @Test 43 | public void testBinaryIndexedChronicleAppenderConfig() throws IOException { 44 | final String loggerName = "config-binary-chronicle"; 45 | final String appenderName = "CONFIG-BINARY-CHRONICLE"; 46 | 47 | final ch.qos.logback.classic.Logger logger = getLoggerContext().getLogger(loggerName); 48 | assertNotNull(logger); 49 | 50 | final ch.qos.logback.core.Appender appender = logger.getAppender(appenderName); 51 | assertNotNull(appender); 52 | assertTrue(appender instanceof ChronicleAppender); 53 | 54 | ChronicleAppender ba = (ChronicleAppender) appender; 55 | assertEquals(128, ba.getChronicleConfig().getBlockSize()); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /logger-logback/src/test/java/net/openhft/chronicle/logger/logback/LogbackTestBase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.logback; 19 | 20 | import ch.qos.logback.classic.LoggerContext; 21 | import net.openhft.chronicle.core.OS; 22 | import net.openhft.chronicle.core.util.Time; 23 | import net.openhft.chronicle.logger.ChronicleLogLevel; 24 | import org.slf4j.Logger; 25 | import org.slf4j.LoggerFactory; 26 | 27 | public class LogbackTestBase { 28 | 29 | // ************************************************************************* 30 | // 31 | // ************************************************************************* 32 | 33 | static final ChronicleLogLevel[] LOG_LEVELS = ChronicleLogLevel.values(); 34 | 35 | static String rootPath() { 36 | String path = System.getProperty("java.io.tmpdir"); 37 | String sep = System.getProperty("file.separator"); 38 | 39 | if (!path.endsWith(sep)) { 40 | path += sep; 41 | } 42 | 43 | return path + "chronicle-logback"; 44 | } 45 | 46 | static String basePath(String type) { 47 | return rootPath() 48 | + System.getProperty("file.separator") 49 | + type; 50 | } 51 | 52 | static void log(Logger logger, ChronicleLogLevel level, String fmt, Object... args) { 53 | switch (level) { 54 | case TRACE: 55 | logger.trace(fmt, args); 56 | break; 57 | 58 | case DEBUG: 59 | logger.debug(fmt, args); 60 | break; 61 | 62 | case INFO: 63 | logger.info(fmt, args); 64 | break; 65 | 66 | case WARN: 67 | logger.warn(fmt, args); 68 | break; 69 | 70 | case ERROR: 71 | logger.error(fmt, args); 72 | break; 73 | default: 74 | throw new UnsupportedOperationException(); 75 | } 76 | } 77 | 78 | // ************************************************************************* 79 | // 80 | // ************************************************************************* 81 | 82 | LoggerContext getLoggerContext() { 83 | return (LoggerContext) LoggerFactory.getILoggerFactory(); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /logger-logback/src/test/resources/logback-chronicle-binary-appender.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 22 | 23 | 25 | 26 | %d %contextName [%t] %level %logger{36} - %msg%n 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 36 | ${java.io.tmpdir}/chronicle-logback/binary-chronicle 37 | false 38 | false 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /logger-logback/src/test/resources/logback-chronicle-config.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 22 | 23 | 25 | 26 | %d %contextName [%t] %level %logger{36} - %msg%n 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 36 | ${java.io.tmpdir}/chronicle-logback/config-binary-chronicle 37 | false 38 | false 39 | 40 | 41 | 128 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /logger-slf4j-2/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 22 | 23 | 4.0.0 24 | 25 | 26 | net.openhft 27 | chronicle-logger 28 | 4.27ea2-SNAPSHOT 29 | ../pom.xml 30 | 31 | 32 | OpenHFT/Chronicle-Logger/logger-slf4j-2 33 | chronicle-logger-slf4j-2 34 | bundle 35 | 36 | 37 | 38 | net.openhft 39 | chronicle-logger-core 40 | 41 | 42 | 43 | 44 | org.slf4j 45 | slf4j-api 46 | 2.0.0 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | org.apache.maven.plugins 55 | maven-surefire-plugin 56 | 57 | 58 | **/*PerfTest.java 59 | 60 | 61 | ${project.build.directory} 62 | 63 | 64 | 65 | 73 | 74 | org.apache.servicemix.tooling 75 | depends-maven-plugin 76 | 77 | 78 | generate-depends-file 79 | 80 | generate-depends-file 81 | 82 | 83 | 84 | 85 | 86 | org.apache.felix 87 | maven-bundle-plugin 88 | true 89 | 90 | 91 | ${project.groupId}.${project.artifactId} 92 | OpenHFT :: ${project.artifactId} 93 | ${project.version} 94 | net.openhft.chronicle.logger.slf4j.* 95 | 96 | 97 | 98 | 102 | 103 | 104 | manifest 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 114 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 115 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 116 | master 117 | 118 | 119 | 120 | -------------------------------------------------------------------------------- /logger-slf4j-2/src/main/java/net/openhft/chronicle/logger/slf4j2/ChronicleLoggerFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.slf4j2; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogManager; 21 | import net.openhft.chronicle.logger.ChronicleLogWriter; 22 | import org.slf4j.ILoggerFactory; 23 | import org.slf4j.Logger; 24 | import org.slf4j.helpers.NOPLogger; 25 | import org.slf4j.impl.SimpleLogger; 26 | 27 | import java.util.Map; 28 | import java.util.concurrent.ConcurrentHashMap; 29 | 30 | /** 31 | * Simple implementation of Logger that sends all enabled slf4j messages, 32 | * for all defined loggers, to one or more VanillaChronicle.. 33 | * 34 | * To configure this sl4j binding you need to specify the location of a properties 35 | * files via system properties: 36 | * {@code -Dchronicle.logger.properties=${pathOfYourPropertiesFile}} 37 | * 38 | * The following system properties are supported to configure the behavior of this 39 | * logger: 40 | * 41 | * {@code chronicle.logger.root.path} 42 | * {@code chronicle.logger.root.level} 43 | * {@code chronicle.logger.root.append} 44 | * 45 | */ 46 | public class ChronicleLoggerFactory implements ILoggerFactory { 47 | private final Map loggers; 48 | private final ChronicleLogManager manager; 49 | 50 | // ************************************************************************* 51 | // 52 | // ************************************************************************* 53 | 54 | /** 55 | * c-tor 56 | */ 57 | public ChronicleLoggerFactory() { 58 | this.loggers = new ConcurrentHashMap<>(); 59 | this.manager = ChronicleLogManager.getInstance(); 60 | } 61 | 62 | // ************************************************************************* 63 | // for testing 64 | // ************************************************************************* 65 | 66 | /** 67 | * Return an appropriate {@link ChronicleLogger} instance by name. 68 | */ 69 | @Override 70 | public Logger getLogger(String name) { 71 | try { 72 | return doGetLogger(name); 73 | } catch (Exception e) { 74 | System.err.println("Unable to initialize chronicle-logger-slf4j (" + name + ")\n " + e.getMessage()); 75 | e.printStackTrace(); 76 | } 77 | 78 | return NOPLogger.NOP_LOGGER; 79 | } 80 | 81 | // ************************************************************************* 82 | // 83 | // ************************************************************************* 84 | 85 | synchronized void reload() { 86 | this.loggers.clear(); 87 | this.manager.reload(); 88 | } 89 | 90 | private synchronized Logger doGetLogger(String name) { 91 | Logger logger = loggers.get(name); 92 | if (logger == null) { 93 | if (name != null && name.startsWith("net.openhft")) { 94 | SimpleLogger.lazyInit(); 95 | logger = new SimpleLogger(name); 96 | } else { 97 | final ChronicleLogWriter writer = manager.getWriter(name); 98 | logger = new ChronicleLogger(writer, name, manager.cfg().getLevel(name)); 99 | } 100 | loggers.put(name, logger); 101 | } 102 | 103 | return logger; 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /logger-slf4j-2/src/main/java/net/openhft/chronicle/logger/slf4j2/internal/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This package and any and all sub-packages contains strictly internal classes for this Chronicle library. 3 | * Internal classes shall never be used directly. 4 | * 5 | * Specifically, the following actions (including, but not limited to) are not allowed 6 | * on internal classes and packages: 7 | * 8 | * Casting to 9 | * Reflection of any kind 10 | * Explicit Serialize/deserialize 11 | * 12 | * 13 | * The classes in this package and any sub-package are subject to 14 | * changes at any time for any reason. 15 | */ 16 | package net.openhft.chronicle.logger.slf4j2.internal; 17 | -------------------------------------------------------------------------------- /logger-slf4j-2/src/main/java/org/slf4j/impl/ChronicleServiceProvider.java: -------------------------------------------------------------------------------- 1 | package org.slf4j.impl; 2 | 3 | import net.openhft.chronicle.logger.slf4j2.ChronicleLoggerFactory; 4 | import org.slf4j.ILoggerFactory; 5 | import org.slf4j.IMarkerFactory; 6 | import org.slf4j.helpers.BasicMarkerFactory; 7 | import org.slf4j.helpers.NOPMDCAdapter; 8 | import org.slf4j.spi.MDCAdapter; 9 | import org.slf4j.spi.SLF4JServiceProvider; 10 | 11 | public class ChronicleServiceProvider implements SLF4JServiceProvider { 12 | 13 | /** 14 | * Declare the version of the SLF4J API this implementation is compiled against. 15 | * The value of this field is modified with each major release. 16 | */ 17 | // to avoid constant folding by the compiler, this field must *not* be final 18 | public static String REQUESTED_API_VERSION = "2.0.99"; // !final 19 | 20 | public ChronicleServiceProvider() {} 21 | /** 22 | * The ILoggerFactory instance returned by the {@link #getLoggerFactory} 23 | * method should always be the same object 24 | */ 25 | private ILoggerFactory loggerFactory; 26 | 27 | private IMarkerFactory markerFactory; 28 | private MDCAdapter mdcAdapter; 29 | 30 | @Override 31 | public ILoggerFactory getLoggerFactory() { 32 | return loggerFactory; 33 | } 34 | 35 | @Override 36 | public IMarkerFactory getMarkerFactory() { 37 | return markerFactory; 38 | } 39 | 40 | @Override 41 | public MDCAdapter getMDCAdapter() { 42 | return mdcAdapter; 43 | } 44 | 45 | @Override 46 | public String getRequestedApiVersion() { 47 | return REQUESTED_API_VERSION; 48 | } 49 | 50 | @Override 51 | public void initialize() { 52 | loggerFactory = new ChronicleLoggerFactory(); 53 | markerFactory = new BasicMarkerFactory(); 54 | mdcAdapter = new NOPMDCAdapter(); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /logger-slf4j-2/src/main/java/org/slf4j/impl/OutputChoice.java: -------------------------------------------------------------------------------- 1 | package org.slf4j.impl; 2 | 3 | import java.io.PrintStream; 4 | 5 | /** 6 | * This class encapsulates the user's choice of output target. 7 | * 8 | * @author Ceki Gülcü 9 | * 10 | */ 11 | class OutputChoice { 12 | 13 | enum OutputChoiceType { 14 | SYS_OUT, CACHED_SYS_OUT, SYS_ERR, CACHED_SYS_ERR, FILE; 15 | } 16 | 17 | final OutputChoiceType outputChoiceType; 18 | final PrintStream targetPrintStream; 19 | 20 | OutputChoice(OutputChoiceType outputChoiceType) { 21 | if (outputChoiceType == OutputChoiceType.FILE) { 22 | throw new IllegalArgumentException(); 23 | } 24 | this.outputChoiceType = outputChoiceType; 25 | if (outputChoiceType == OutputChoiceType.CACHED_SYS_OUT) { 26 | this.targetPrintStream = System.out; 27 | } else if (outputChoiceType == OutputChoiceType.CACHED_SYS_ERR) { 28 | this.targetPrintStream = System.err; 29 | } else { 30 | this.targetPrintStream = null; 31 | } 32 | } 33 | 34 | OutputChoice(PrintStream printStream) { 35 | this.outputChoiceType = OutputChoiceType.FILE; 36 | this.targetPrintStream = printStream; 37 | } 38 | 39 | PrintStream getTargetPrintStream() { 40 | switch (outputChoiceType) { 41 | case SYS_OUT: 42 | return System.out; 43 | case SYS_ERR: 44 | return System.err; 45 | case CACHED_SYS_ERR: 46 | case CACHED_SYS_OUT: 47 | case FILE: 48 | return targetPrintStream; 49 | default: 50 | throw new IllegalArgumentException(); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /logger-slf4j-2/src/main/resources/META-INF/services/org.slf4j.spi.SLF4JServiceProvider: -------------------------------------------------------------------------------- 1 | org.slf4j.impl.ChronicleServiceProvider 2 | -------------------------------------------------------------------------------- /logger-slf4j-2/src/test/java/net/openhft/chronicle/logger/slf4j2/ChronicleLoggingConfigTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.slf4j2; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogConfig; 21 | import org.junit.Test; 22 | 23 | import static org.junit.Assert.assertNotNull; 24 | 25 | public class ChronicleLoggingConfigTest { 26 | @Test 27 | public void testLoadClasspathIndexed() { 28 | System.setProperty("chronicle.logger.properties", "chronicle.logger.properties"); 29 | assertLoadsValidConfig(); 30 | } 31 | 32 | private void assertLoadsValidConfig() { 33 | ChronicleLogConfig config = ChronicleLogConfig.load(); 34 | assertNotNull("unable to load config", config); 35 | assertNotNull("is not a valid config", config.getAppenderConfig()); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /logger-slf4j-2/src/test/java/net/openhft/chronicle/logger/slf4j2/Slf4jChronicleConfigurationTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.slf4j2; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogConfig; 21 | import net.openhft.chronicle.logger.ChronicleLogLevel; 22 | import org.junit.Test; 23 | 24 | import java.io.File; 25 | import java.util.Properties; 26 | 27 | import static org.junit.Assert.assertEquals; 28 | import static org.junit.Assert.assertNotNull; 29 | 30 | public class Slf4jChronicleConfigurationTest extends Slf4jTestBase { 31 | 32 | @Test 33 | public void testLoadProperties() { 34 | final String cfgPath = "chronicle.logger.properties"; 35 | final ChronicleLogConfig cfg = ChronicleLogConfig.load(cfgPath); 36 | 37 | assertNotNull(cfg); 38 | 39 | assertEquals( 40 | new File(basePath("root")), 41 | new File(cfg.getString(ChronicleLogConfig.KEY_PATH))); 42 | assertEquals( 43 | ChronicleLogLevel.DEBUG.toString(), 44 | cfg.getString(ChronicleLogConfig.KEY_LEVEL).toUpperCase()); 45 | assertEquals("false", cfg.getString(ChronicleLogConfig.KEY_APPEND)); 46 | assertEquals( 47 | new File(basePath("logger_1")), 48 | new File(cfg.getString("logger_1", ChronicleLogConfig.KEY_PATH))); 49 | assertEquals( 50 | ChronicleLogLevel.INFO.toString(), 51 | cfg.getString("logger_1", ChronicleLogConfig.KEY_LEVEL).toUpperCase()); 52 | assertEquals( 53 | ChronicleLogLevel.DEBUG.toString(), 54 | cfg.getString("readwrite", ChronicleLogConfig.KEY_LEVEL).toUpperCase()); 55 | } 56 | 57 | @Test 58 | public void testLoadConfig() { 59 | final Properties properties = new Properties(); 60 | properties.setProperty("chronicle.logger.root.cfg.blockSize", "256"); 61 | 62 | final ChronicleLogConfig clc = ChronicleLogConfig.load(properties); 63 | assertNotNull(clc.getAppenderConfig()); 64 | 65 | assertEquals(256, clc.getAppenderConfig().getBlockSize()); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /logger-slf4j-2/src/test/java/net/openhft/chronicle/logger/slf4j2/Slf4jChronicleLoggerPerfTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.slf4j2; 19 | 20 | import net.openhft.chronicle.core.io.IOTools; 21 | import org.apache.commons.lang3.StringUtils; 22 | import org.junit.After; 23 | import org.junit.Before; 24 | import org.junit.Ignore; 25 | import org.junit.Test; 26 | import org.slf4j.Logger; 27 | import org.slf4j.LoggerFactory; 28 | 29 | import java.util.concurrent.ExecutorService; 30 | import java.util.concurrent.Executors; 31 | import java.util.concurrent.TimeUnit; 32 | 33 | @Ignore 34 | public class Slf4jChronicleLoggerPerfTest extends Slf4jTestBase { 35 | 36 | // ************************************************************************* 37 | // 38 | // ************************************************************************* 39 | 40 | @Before 41 | public void setUp() { 42 | System.setProperty( 43 | "chronicle.logger.properties", 44 | "chronicle.logger.perf.properties"); 45 | 46 | getChronicleLoggerFactory().reload(); 47 | } 48 | 49 | @After 50 | public void tearDown() { 51 | IOTools.deleteDirWithFiles(basePath()); 52 | } 53 | 54 | // ************************************************************************* 55 | // Single Thread 56 | // ************************************************************************* 57 | 58 | @Test 59 | public void testSingleThreadLogging1() { 60 | Thread.currentThread().setName("perf-plain"); 61 | 62 | final String testId = "perf-chronicle"; 63 | final Logger clogger = LoggerFactory.getLogger(testId); 64 | final long items = 1000000; 65 | 66 | warmup(clogger); 67 | 68 | for (int s = 64; s <= 1024; s += 64) { 69 | final String staticStr = StringUtils.leftPad("", s, 'X'); 70 | 71 | long cStart1 = System.nanoTime(); 72 | 73 | for (int i = 1; i <= items; i++) { 74 | clogger.info(staticStr); 75 | } 76 | 77 | long cEnd1 = System.nanoTime(); 78 | 79 | System.out.printf("items=%03d size=%04d => chronology=%.3f ms, chronology-average=%.3f us\n", 80 | items, 81 | staticStr.length(), 82 | (cEnd1 - cStart1) / 1e6, 83 | (cEnd1 - cStart1) / items / 1e3); 84 | } 85 | } 86 | 87 | @Test 88 | public void testSingleThreadLogging2() { 89 | Thread.currentThread().setName("perf-plain"); 90 | 91 | final String testId = "perf-chronicle"; 92 | final Logger clogger = LoggerFactory.getLogger(testId); 93 | final long items = 1000000; 94 | final String strFmt = StringUtils.leftPad("> v1={}, v2={}, v3={}", 32, 'X'); 95 | 96 | warmup(clogger); 97 | 98 | for (int n = 0; n < 10; n++) { 99 | long cStart1 = System.nanoTime(); 100 | 101 | for (int i = 1; i <= items; i++) { 102 | clogger.info(strFmt, i, i * 10, i / 16); 103 | } 104 | 105 | long cEnd1 = System.nanoTime(); 106 | 107 | System.out.printf("items=%03d => chronology=%.3f ms, chronology-average=%.3f us\n", 108 | items, 109 | (cEnd1 - cStart1) / 1e6, 110 | (cEnd1 - cStart1) / items / 1e3); 111 | } 112 | } 113 | 114 | // ************************************************************************* 115 | // Multi Thread 116 | // ************************************************************************* 117 | 118 | @Test 119 | public void testMultiThreadLogging() throws InterruptedException { 120 | warmup(LoggerFactory.getLogger("perf-chronicle")); 121 | 122 | final int RUNS = 1000000; 123 | final int THREADS = 10; 124 | 125 | for (int size : new int[]{64, 128, 256}) { 126 | { 127 | final long start = System.nanoTime(); 128 | 129 | ExecutorService es = Executors.newFixedThreadPool(THREADS); 130 | for (int t = 0; t < THREADS; t++) { 131 | es.submit(new RunnableLogger(RUNS, size, "perf-chronicle")); 132 | } 133 | 134 | es.shutdown(); 135 | es.awaitTermination(5, TimeUnit.SECONDS); 136 | 137 | final long time = System.nanoTime() - start; 138 | 139 | System.out.printf("ChronicleLog.MT (runs=%d, min size=%03d, elapsed=%.3f ms) took an average of %.3f us per entry\n", 140 | RUNS, 141 | size, 142 | time / 1e6, 143 | time / 1e3 / (RUNS * THREADS) 144 | ); 145 | } 146 | } 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /logger-slf4j-2/src/test/java/net/openhft/chronicle/logger/slf4j2/Slf4jTestBase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.slf4j2; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogLevel; 21 | import net.openhft.chronicle.logger.slf4j2.ChronicleLoggerFactory; 22 | import org.apache.commons.lang3.StringUtils; 23 | import org.slf4j.Logger; 24 | import org.slf4j.LoggerFactory; 25 | import org.slf4j.impl.ChronicleServiceProvider; 26 | 27 | class Slf4jTestBase { 28 | 29 | // ************************************************************************* 30 | // 31 | // ************************************************************************* 32 | 33 | static final ChronicleLogLevel[] LOG_LEVELS = ChronicleLogLevel.values(); 34 | 35 | static String basePath() { 36 | String path = System.getProperty("java.io.tmpdir"); 37 | String sep = System.getProperty("file.separator"); 38 | 39 | if (!path.endsWith(sep)) { 40 | path += sep; 41 | } 42 | 43 | return path + "chronicle-slf4j"; 44 | } 45 | 46 | static String basePath(String loggerName) { 47 | return basePath() 48 | + System.getProperty("file.separator") 49 | + loggerName; 50 | } 51 | 52 | static void log(Logger logger, ChronicleLogLevel level, String fmt, Object... args) { 53 | switch (level) { 54 | case TRACE: 55 | logger.trace(fmt, args); 56 | break; 57 | 58 | case DEBUG: 59 | logger.debug(fmt, args); 60 | break; 61 | 62 | case INFO: 63 | logger.info(fmt, args); 64 | break; 65 | 66 | case WARN: 67 | logger.warn(fmt, args); 68 | break; 69 | 70 | case ERROR: 71 | logger.error(fmt, args); 72 | break; 73 | default: 74 | throw new UnsupportedOperationException(); 75 | } 76 | } 77 | 78 | static void warmup(Logger logger) { 79 | for (int i = 0; i < 10; i++) { 80 | logger.info("warmup"); 81 | } 82 | } 83 | 84 | // ************************************************************************* 85 | // 86 | // ************************************************************************* 87 | 88 | /** 89 | * @return the ChronicleLoggerFactory singleton 90 | */ 91 | ChronicleLoggerFactory getChronicleLoggerFactory() { 92 | ChronicleServiceProvider provider = new ChronicleServiceProvider(); 93 | provider.initialize(); 94 | return (ChronicleLoggerFactory) provider.getLoggerFactory(); 95 | } 96 | 97 | // ************************************************************************* 98 | // 99 | // ************************************************************************* 100 | 101 | protected final class RunnableLogger implements Runnable { 102 | private final Logger logger; 103 | private final int runs; 104 | private final String fmt; 105 | private final String fmtBase = " > val1={}, val2={}, val3={}"; 106 | 107 | public RunnableLogger(int runs, int pad, String loggerName) { 108 | this.logger = LoggerFactory.getLogger(loggerName); 109 | this.runs = runs; 110 | this.fmt = StringUtils.rightPad(fmtBase, pad + fmtBase.length() - (4 + 8 + 8), "X"); 111 | } 112 | 113 | @Override 114 | public void run() { 115 | for (int i = 0; i < this.runs; i++) { 116 | this.logger.info(fmt, i, i * 7L, i / 16.0); 117 | } 118 | } 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /logger-slf4j-2/src/test/resources/chronicle.logger.perf.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2014-2017 Chronicle Software 3 | # 4 | # https://chronicle.software 5 | # 6 | # This program is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License 16 | # along with this program. If not, see . 17 | # 18 | 19 | chronicle.logger.base = ${java.io.tmpdir}/chronicle-slf4j 20 | 21 | chronicle.logger.root.path = ${chronicle.logger.base}/perf 22 | chronicle.logger.root.level = debug 23 | chronicle.logger.root.append = false 24 | -------------------------------------------------------------------------------- /logger-slf4j-2/src/test/resources/chronicle.logger.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2014-2017 Chronicle Software 3 | # 4 | # https://chronicle.software 5 | # 6 | # This program is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License 16 | # along with this program. If not, see . 17 | # 18 | 19 | ################################################################################ 20 | # Common 21 | ################################################################################ 22 | 23 | chronicle.logger.base = ${java.io.tmpdir}/chronicle-slf4j 24 | chronicle.logger.root.path = ${chronicle.logger.base}/root 25 | chronicle.logger.root.level = debug 26 | chronicle.logger.root.append = false 27 | 28 | ################################################################################ 29 | # Loggers 30 | ################################################################################ 31 | 32 | # logger : Logger1 33 | chronicle.logger.logger_1.path = ${chronicle.logger.base}/logger_1 34 | chronicle.logger.logger_1.level = info 35 | 36 | # logger : impl 37 | chronicle.logger.readwrite.path = ${chronicle.logger.base}/readwrite 38 | -------------------------------------------------------------------------------- /logger-slf4j/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 22 | 23 | 4.0.0 24 | 25 | 26 | net.openhft 27 | chronicle-logger 28 | 4.27ea2-SNAPSHOT 29 | ../pom.xml 30 | 31 | 32 | OpenHFT/Chronicle-Logger/logger-slf4j 33 | chronicle-logger-slf4j 34 | bundle 35 | 36 | 37 | 38 | net.openhft 39 | chronicle-logger-core 40 | 41 | 42 | 43 | 44 | org.slf4j 45 | slf4j-api 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | org.apache.maven.plugins 54 | maven-surefire-plugin 55 | 56 | 57 | **/*PerfTest.java 58 | 59 | 60 | ${project.build.directory} 61 | 62 | 63 | 64 | 72 | 73 | org.apache.servicemix.tooling 74 | depends-maven-plugin 75 | 76 | 77 | generate-depends-file 78 | 79 | generate-depends-file 80 | 81 | 82 | 83 | 84 | 85 | org.apache.felix 86 | maven-bundle-plugin 87 | true 88 | 89 | 90 | ${project.groupId}.${project.artifactId} 91 | OpenHFT :: ${project.artifactId} 92 | ${project.version} 93 | net.openhft.chronicle.logger.slf4j.* 94 | 95 | 96 | 97 | 101 | 102 | 103 | manifest 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 113 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 114 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 115 | master 116 | 117 | 118 | 119 | -------------------------------------------------------------------------------- /logger-slf4j/src/main/java/net/openhft/chronicle/logger/slf4j/ChronicleLoggerFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.slf4j; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogManager; 21 | import net.openhft.chronicle.logger.ChronicleLogWriter; 22 | import org.slf4j.ILoggerFactory; 23 | import org.slf4j.Logger; 24 | import org.slf4j.helpers.NOPLogger; 25 | import org.slf4j.impl.SimpleLogger; 26 | 27 | import java.util.Map; 28 | import java.util.concurrent.ConcurrentHashMap; 29 | 30 | /** 31 | * Simple implementation of Logger that sends all enabled slf4j messages, 32 | * for all defined loggers, to one or more VanillaChronicle.. 33 | * 34 | * To configure this sl4j binding you need to specify the location of a properties 35 | * files via system properties: 36 | * {@code -Dchronicle.logger.properties=${pathOfYourPropertiesFile}} 37 | * 38 | * The following system properties are supported to configure the behavior of this 39 | * logger: 40 | * 41 | * {@code chronicle.logger.root.path} 42 | * {@code chronicle.logger.root.level} 43 | * {@code chronicle.logger.root.append} 44 | * 45 | */ 46 | public class ChronicleLoggerFactory implements ILoggerFactory { 47 | private final Map loggers; 48 | private final ChronicleLogManager manager; 49 | 50 | // ************************************************************************* 51 | // 52 | // ************************************************************************* 53 | 54 | /** 55 | * c-tor 56 | */ 57 | public ChronicleLoggerFactory() { 58 | this.loggers = new ConcurrentHashMap<>(); 59 | this.manager = ChronicleLogManager.getInstance(); 60 | } 61 | 62 | // ************************************************************************* 63 | // for testing 64 | // ************************************************************************* 65 | 66 | /** 67 | * Return an appropriate {@link ChronicleLogger} instance by name. 68 | */ 69 | @Override 70 | public Logger getLogger(String name) { 71 | try { 72 | return doGetLogger(name); 73 | } catch (Exception e) { 74 | System.err.println("Unable to initialize chronicle-logger-slf4j (" + name + ")\n " + e.getMessage()); 75 | e.printStackTrace(); 76 | } 77 | 78 | return NOPLogger.NOP_LOGGER; 79 | } 80 | 81 | // ************************************************************************* 82 | // 83 | // ************************************************************************* 84 | 85 | synchronized void reload() { 86 | this.loggers.clear(); 87 | this.manager.reload(); 88 | } 89 | 90 | private synchronized Logger doGetLogger(String name) { 91 | Logger logger = loggers.get(name); 92 | if (logger == null) { 93 | if (name != null && name.startsWith("net.openhft")) { 94 | SimpleLogger.lazyInit(); 95 | logger = new SimpleLogger(name); 96 | } else { 97 | final ChronicleLogWriter writer = manager.getWriter(name); 98 | logger = new ChronicleLogger(writer, name, manager.cfg().getLevel(name)); 99 | } 100 | loggers.put(name, logger); 101 | } 102 | 103 | return logger; 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /logger-slf4j/src/main/java/net/openhft/chronicle/logger/slf4j/internal/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This package and any and all sub-packages contains strictly internal classes for this Chronicle library. 3 | * Internal classes shall never be used directly. 4 | * 5 | * Specifically, the following actions (including, but not limited to) are not allowed 6 | * on internal classes and packages: 7 | * 8 | * Casting to 9 | * Reflection of any kind 10 | * Explicit Serialize/deserialize 11 | * 12 | * 13 | * The classes in this package and any sub-package are subject to 14 | * changes at any time for any reason. 15 | */ 16 | package net.openhft.chronicle.logger.slf4j.internal; 17 | -------------------------------------------------------------------------------- /logger-slf4j/src/main/java/org/slf4j/impl/OutputChoice.java: -------------------------------------------------------------------------------- 1 | package org.slf4j.impl; 2 | 3 | import java.io.PrintStream; 4 | 5 | /** 6 | * This class encapsulates the user's choice of output target. 7 | * 8 | * @author Ceki Gülcü 9 | * 10 | */ 11 | class OutputChoice { 12 | 13 | enum OutputChoiceType { 14 | SYS_OUT, CACHED_SYS_OUT, SYS_ERR, CACHED_SYS_ERR, FILE; 15 | } 16 | 17 | final OutputChoiceType outputChoiceType; 18 | final PrintStream targetPrintStream; 19 | 20 | OutputChoice(OutputChoiceType outputChoiceType) { 21 | if (outputChoiceType == OutputChoiceType.FILE) { 22 | throw new IllegalArgumentException(); 23 | } 24 | this.outputChoiceType = outputChoiceType; 25 | if (outputChoiceType == OutputChoiceType.CACHED_SYS_OUT) { 26 | this.targetPrintStream = System.out; 27 | } else if (outputChoiceType == OutputChoiceType.CACHED_SYS_ERR) { 28 | this.targetPrintStream = System.err; 29 | } else { 30 | this.targetPrintStream = null; 31 | } 32 | } 33 | 34 | OutputChoice(PrintStream printStream) { 35 | this.outputChoiceType = OutputChoiceType.FILE; 36 | this.targetPrintStream = printStream; 37 | } 38 | 39 | PrintStream getTargetPrintStream() { 40 | switch (outputChoiceType) { 41 | case SYS_OUT: 42 | return System.out; 43 | case SYS_ERR: 44 | return System.err; 45 | case CACHED_SYS_ERR: 46 | case CACHED_SYS_OUT: 47 | case FILE: 48 | return targetPrintStream; 49 | default: 50 | throw new IllegalArgumentException(); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /logger-slf4j/src/main/java/org/slf4j/impl/StaticLoggerBinder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.slf4j.impl; 19 | 20 | import net.openhft.chronicle.logger.slf4j.ChronicleLoggerFactory; 21 | import org.slf4j.ILoggerFactory; 22 | import org.slf4j.spi.LoggerFactoryBinder; 23 | 24 | public class StaticLoggerBinder implements LoggerFactoryBinder { 25 | 26 | private static final StaticLoggerBinder SINGLETON = new StaticLoggerBinder(); 27 | private static final String loggerFactoryClassStr = ChronicleLoggerFactory.class.getName(); 28 | /** 29 | * Declare the version of the SLF4J API this implementation is compiled 30 | * against. The value of this field is usually modified with each release. 31 | */ 32 | // to avoid constant folding by the compiler, this field must *not* be final 33 | public static String REQUESTED_API_VERSION = "1.7.30"; // !final 34 | /** 35 | * The ILoggerFactory instance returned by the {@link #getLoggerFactory} 36 | * method should always be the same object 37 | */ 38 | private final ILoggerFactory loggerFactory; 39 | 40 | /** 41 | * c-tor 42 | */ 43 | private StaticLoggerBinder() { 44 | loggerFactory = new ChronicleLoggerFactory(); 45 | } 46 | 47 | /** 48 | * Return the singleton of this class. 49 | * 50 | * @return the StaticLoggerBinder singleton 51 | */ 52 | public static final StaticLoggerBinder getSingleton() { 53 | return SINGLETON; 54 | } 55 | 56 | @Override 57 | public ILoggerFactory getLoggerFactory() { 58 | return loggerFactory; 59 | } 60 | 61 | @Override 62 | public String getLoggerFactoryClassStr() { 63 | return loggerFactoryClassStr; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /logger-slf4j/src/main/java/org/slf4j/impl/StaticMarkerBinder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.slf4j.impl; 19 | 20 | import org.slf4j.IMarkerFactory; 21 | import org.slf4j.helpers.BasicMarkerFactory; 22 | import org.slf4j.spi.MarkerFactoryBinder; 23 | 24 | /** 25 | * The binding of {@link org.slf4j.MarkerFactory} class with an actual instance of 26 | * {@link IMarkerFactory} is performed using information returned by this class. 27 | * 28 | * @author Ceki Gülcü 29 | */ 30 | public class StaticMarkerBinder implements MarkerFactoryBinder { 31 | 32 | /** 33 | * The unique instance of this class. 34 | */ 35 | public static final StaticMarkerBinder SINGLETON = new StaticMarkerBinder(); 36 | 37 | final IMarkerFactory markerFactory = new BasicMarkerFactory(); 38 | 39 | private StaticMarkerBinder() { 40 | } 41 | 42 | /** 43 | * Currently this method always returns an instance of 44 | * {@link BasicMarkerFactory}. 45 | */ 46 | @Override 47 | public IMarkerFactory getMarkerFactory() { 48 | return markerFactory; 49 | } 50 | 51 | /** 52 | * Currently, this method returns the class name of 53 | * {@link BasicMarkerFactory}. 54 | */ 55 | @Override 56 | public String getMarkerFactoryClassStr() { 57 | return BasicMarkerFactory.class.getName(); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /logger-slf4j/src/test/java/net/openhft/chronicle/logger/slf4j/ChronicleLoggingConfigTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.slf4j; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogConfig; 21 | import org.junit.Test; 22 | 23 | import static org.junit.Assert.assertNotNull; 24 | 25 | public class ChronicleLoggingConfigTest { 26 | @Test 27 | public void testLoadClasspathIndexed() { 28 | System.setProperty("chronicle.logger.properties", "chronicle.logger.properties"); 29 | assertLoadsValidConfig(); 30 | } 31 | 32 | private void assertLoadsValidConfig() { 33 | ChronicleLogConfig config = ChronicleLogConfig.load(); 34 | assertNotNull("unable to load config", config); 35 | assertNotNull("is not a valid config", config.getAppenderConfig()); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /logger-slf4j/src/test/java/net/openhft/chronicle/logger/slf4j/Slf4jChronicleConfigurationTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.slf4j; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogConfig; 21 | import net.openhft.chronicle.logger.ChronicleLogLevel; 22 | import org.junit.Test; 23 | 24 | import java.io.File; 25 | import java.util.Properties; 26 | 27 | import static org.junit.Assert.assertEquals; 28 | import static org.junit.Assert.assertNotNull; 29 | 30 | public class Slf4jChronicleConfigurationTest extends Slf4jTestBase { 31 | 32 | @Test 33 | public void testLoadProperties() { 34 | final String cfgPath = "chronicle.logger.properties"; 35 | final ChronicleLogConfig cfg = ChronicleLogConfig.load(cfgPath); 36 | 37 | assertNotNull(cfg); 38 | 39 | assertEquals( 40 | new File(basePath("root")), 41 | new File(cfg.getString(ChronicleLogConfig.KEY_PATH))); 42 | assertEquals( 43 | ChronicleLogLevel.DEBUG.toString(), 44 | cfg.getString(ChronicleLogConfig.KEY_LEVEL).toUpperCase()); 45 | assertEquals("false", cfg.getString(ChronicleLogConfig.KEY_APPEND)); 46 | assertEquals( 47 | new File(basePath("logger_1")), 48 | new File(cfg.getString("logger_1", ChronicleLogConfig.KEY_PATH))); 49 | assertEquals( 50 | ChronicleLogLevel.INFO.toString(), 51 | cfg.getString("logger_1", ChronicleLogConfig.KEY_LEVEL).toUpperCase()); 52 | assertEquals( 53 | ChronicleLogLevel.DEBUG.toString(), 54 | cfg.getString("readwrite", ChronicleLogConfig.KEY_LEVEL).toUpperCase()); 55 | } 56 | 57 | @Test 58 | public void testLoadConfig() { 59 | final Properties properties = new Properties(); 60 | properties.setProperty("chronicle.logger.root.cfg.blockSize", "256"); 61 | 62 | final ChronicleLogConfig clc = ChronicleLogConfig.load(properties); 63 | assertNotNull(clc.getAppenderConfig()); 64 | 65 | assertEquals(256, clc.getAppenderConfig().getBlockSize()); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /logger-slf4j/src/test/java/net/openhft/chronicle/logger/slf4j/Slf4jChronicleLoggerPerfTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.slf4j; 19 | 20 | import net.openhft.chronicle.core.io.IOTools; 21 | import org.apache.commons.lang3.StringUtils; 22 | import org.junit.After; 23 | import org.junit.Before; 24 | import org.junit.Ignore; 25 | import org.junit.Test; 26 | import org.slf4j.Logger; 27 | import org.slf4j.LoggerFactory; 28 | 29 | import java.util.concurrent.ExecutorService; 30 | import java.util.concurrent.Executors; 31 | import java.util.concurrent.TimeUnit; 32 | 33 | @Ignore 34 | public class Slf4jChronicleLoggerPerfTest extends Slf4jTestBase { 35 | 36 | // ************************************************************************* 37 | // 38 | // ************************************************************************* 39 | 40 | @Before 41 | public void setUp() { 42 | System.setProperty( 43 | "chronicle.logger.properties", 44 | "chronicle.logger.perf.properties"); 45 | 46 | getChronicleLoggerFactory().reload(); 47 | } 48 | 49 | @After 50 | public void tearDown() { 51 | IOTools.deleteDirWithFiles(basePath()); 52 | } 53 | 54 | // ************************************************************************* 55 | // Single Thread 56 | // ************************************************************************* 57 | 58 | @Test 59 | public void testSingleThreadLogging1() { 60 | Thread.currentThread().setName("perf-plain"); 61 | 62 | final String testId = "perf-chronicle"; 63 | final Logger clogger = LoggerFactory.getLogger(testId); 64 | final long items = 1000000; 65 | 66 | warmup(clogger); 67 | 68 | for (int s = 64; s <= 1024; s += 64) { 69 | final String staticStr = StringUtils.leftPad("", s, 'X'); 70 | 71 | long cStart1 = System.nanoTime(); 72 | 73 | for (int i = 1; i <= items; i++) { 74 | clogger.info(staticStr); 75 | } 76 | 77 | long cEnd1 = System.nanoTime(); 78 | 79 | System.out.printf("items=%03d size=%04d => chronology=%.3f ms, chronology-average=%.3f us\n", 80 | items, 81 | staticStr.length(), 82 | (cEnd1 - cStart1) / 1e6, 83 | (cEnd1 - cStart1) / items / 1e3); 84 | } 85 | } 86 | 87 | @Test 88 | public void testSingleThreadLogging2() { 89 | Thread.currentThread().setName("perf-plain"); 90 | 91 | final String testId = "perf-chronicle"; 92 | final Logger clogger = LoggerFactory.getLogger(testId); 93 | final long items = 1000000; 94 | final String strFmt = StringUtils.leftPad("> v1={}, v2={}, v3={}", 32, 'X'); 95 | 96 | warmup(clogger); 97 | 98 | for (int n = 0; n < 10; n++) { 99 | long cStart1 = System.nanoTime(); 100 | 101 | for (int i = 1; i <= items; i++) { 102 | clogger.info(strFmt, i, i * 10, i / 16); 103 | } 104 | 105 | long cEnd1 = System.nanoTime(); 106 | 107 | System.out.printf("items=%03d => chronology=%.3f ms, chronology-average=%.3f us\n", 108 | items, 109 | (cEnd1 - cStart1) / 1e6, 110 | (cEnd1 - cStart1) / items / 1e3); 111 | } 112 | } 113 | 114 | // ************************************************************************* 115 | // Multi Thread 116 | // ************************************************************************* 117 | 118 | @Test 119 | public void testMultiThreadLogging() throws InterruptedException { 120 | warmup(LoggerFactory.getLogger("perf-chronicle")); 121 | 122 | final int RUNS = 1000000; 123 | final int THREADS = 10; 124 | 125 | for (int size : new int[]{64, 128, 256}) { 126 | { 127 | final long start = System.nanoTime(); 128 | 129 | ExecutorService es = Executors.newFixedThreadPool(THREADS); 130 | for (int t = 0; t < THREADS; t++) { 131 | es.submit(new RunnableLogger(RUNS, size, "perf-chronicle")); 132 | } 133 | 134 | es.shutdown(); 135 | es.awaitTermination(5, TimeUnit.SECONDS); 136 | 137 | final long time = System.nanoTime() - start; 138 | 139 | System.out.printf("ChronicleLog.MT (runs=%d, min size=%03d, elapsed=%.3f ms) took an average of %.3f us per entry\n", 140 | RUNS, 141 | size, 142 | time / 1e6, 143 | time / 1e3 / (RUNS * THREADS) 144 | ); 145 | } 146 | } 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /logger-slf4j/src/test/java/net/openhft/chronicle/logger/slf4j/Slf4jTestBase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.slf4j; 19 | 20 | import net.openhft.chronicle.core.OS; 21 | import net.openhft.chronicle.core.util.Time; 22 | import net.openhft.chronicle.logger.ChronicleLogLevel; 23 | import org.apache.commons.lang3.StringUtils; 24 | import org.slf4j.Logger; 25 | import org.slf4j.LoggerFactory; 26 | import org.slf4j.impl.StaticLoggerBinder; 27 | 28 | class Slf4jTestBase { 29 | 30 | // ************************************************************************* 31 | // 32 | // ************************************************************************* 33 | 34 | static final ChronicleLogLevel[] LOG_LEVELS = ChronicleLogLevel.values(); 35 | 36 | static String basePath() { 37 | String path = System.getProperty("java.io.tmpdir"); 38 | String sep = System.getProperty("file.separator"); 39 | 40 | if (!path.endsWith(sep)) { 41 | path += sep; 42 | } 43 | 44 | return path + "chronicle-slf4j"; 45 | } 46 | 47 | static String basePath(String loggerName) { 48 | return basePath() 49 | + System.getProperty("file.separator") 50 | + loggerName; 51 | } 52 | 53 | static void log(Logger logger, ChronicleLogLevel level, String fmt, Object... args) { 54 | switch (level) { 55 | case TRACE: 56 | logger.trace(fmt, args); 57 | break; 58 | 59 | case DEBUG: 60 | logger.debug(fmt, args); 61 | break; 62 | 63 | case INFO: 64 | logger.info(fmt, args); 65 | break; 66 | 67 | case WARN: 68 | logger.warn(fmt, args); 69 | break; 70 | 71 | case ERROR: 72 | logger.error(fmt, args); 73 | break; 74 | default: 75 | throw new UnsupportedOperationException(); 76 | } 77 | } 78 | 79 | static void warmup(Logger logger) { 80 | for (int i = 0; i < 10; i++) { 81 | logger.info("warmup"); 82 | } 83 | } 84 | 85 | // ************************************************************************* 86 | // 87 | // ************************************************************************* 88 | 89 | /** 90 | * @return the ChronicleLoggerFactory singleton 91 | */ 92 | ChronicleLoggerFactory getChronicleLoggerFactory() { 93 | return (ChronicleLoggerFactory) StaticLoggerBinder.getSingleton().getLoggerFactory(); 94 | } 95 | 96 | // ************************************************************************* 97 | // 98 | // ************************************************************************* 99 | 100 | protected final class RunnableLogger implements Runnable { 101 | private final Logger logger; 102 | private final int runs; 103 | private final String fmt; 104 | private final String fmtBase = " > val1={}, val2={}, val3={}"; 105 | 106 | public RunnableLogger(int runs, int pad, String loggerName) { 107 | this.logger = LoggerFactory.getLogger(loggerName); 108 | this.runs = runs; 109 | this.fmt = StringUtils.rightPad(fmtBase, pad + fmtBase.length() - (4 + 8 + 8), "X"); 110 | } 111 | 112 | @Override 113 | public void run() { 114 | for (int i = 0; i < this.runs; i++) { 115 | this.logger.info(fmt, i, i * 7L, i / 16.0); 116 | } 117 | } 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /logger-slf4j/src/test/resources/chronicle.logger.perf.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2014-2017 Chronicle Software 3 | # 4 | # https://chronicle.software 5 | # 6 | # This program is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License 16 | # along with this program. If not, see . 17 | # 18 | 19 | chronicle.logger.base = ${java.io.tmpdir}/chronicle-slf4j 20 | 21 | chronicle.logger.root.path = ${chronicle.logger.base}/perf 22 | chronicle.logger.root.level = debug 23 | chronicle.logger.root.append = false 24 | -------------------------------------------------------------------------------- /logger-slf4j/src/test/resources/chronicle.logger.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2014-2017 Chronicle Software 3 | # 4 | # https://chronicle.software 5 | # 6 | # This program is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License 16 | # along with this program. If not, see . 17 | # 18 | 19 | ################################################################################ 20 | # Common 21 | ################################################################################ 22 | 23 | chronicle.logger.base = ${java.io.tmpdir}/chronicle-slf4j 24 | chronicle.logger.root.path = ${chronicle.logger.base}/root 25 | chronicle.logger.root.level = debug 26 | chronicle.logger.root.append = false 27 | 28 | ################################################################################ 29 | # Loggers 30 | ################################################################################ 31 | 32 | # logger : Logger1 33 | chronicle.logger.logger_1.path = ${chronicle.logger.base}/logger_1 34 | chronicle.logger.logger_1.level = info 35 | 36 | # logger : impl 37 | chronicle.logger.readwrite.path = ${chronicle.logger.base}/readwrite 38 | -------------------------------------------------------------------------------- /logger-tools/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 22 | 23 | 4.0.0 24 | 25 | 26 | net.openhft 27 | chronicle-logger 28 | 4.27ea2-SNAPSHOT 29 | ../pom.xml 30 | 31 | 32 | OpenHFT/Chronicle-Logger/logger-tools 33 | chronicle-logger-tools 34 | bundle 35 | 36 | 37 | 38 | net.openhft 39 | chronicle-logger-core 40 | 41 | 42 | 43 | net.openhft 44 | chronicle-wire 45 | 46 | 47 | 48 | 49 | org.slf4j 50 | slf4j-api 51 | 52 | 53 | 54 | 55 | net.openhft 56 | chronicle-logger-logback 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | org.apache.maven.plugins 65 | maven-surefire-plugin 66 | 67 | 1 68 | false 69 | 70 | **/*PerfTest.java 71 | 72 | 73 | ${project.build.directory} 74 | 75 | 76 | 77 | 85 | 86 | org.apache.servicemix.tooling 87 | depends-maven-plugin 88 | 89 | 90 | generate-depends-file 91 | 92 | generate-depends-file 93 | 94 | 95 | 96 | 97 | 98 | org.apache.felix 99 | maven-bundle-plugin 100 | true 101 | 102 | 103 | ${project.groupId}.${project.artifactId} 104 | OpenHFT :: ${project.artifactId} 105 | ${project.version} 106 | net.openhft.chronicle.logger.tools.* 107 | 108 | 109 | 110 | 114 | 115 | 116 | manifest 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 126 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 127 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 128 | master 129 | 130 | 131 | 132 | -------------------------------------------------------------------------------- /logger-tools/src/main/java/net/openhft/chronicle/logger/tools/ChroniCat.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.tools; 19 | 20 | import net.openhft.chronicle.wire.WireType; 21 | 22 | public final class ChroniCat { 23 | 24 | private ChroniCat() { 25 | } 26 | 27 | public static void main(String[] args) { 28 | try { 29 | 30 | if (args.length >= 1) { 31 | int i = 0; 32 | final WireType wt; 33 | if ("-w".equals(args[i])) { 34 | wt = WireType.valueOf(args[++i].trim().toUpperCase()); 35 | i++; 36 | } else { 37 | wt = WireType.BINARY_LIGHT; 38 | } 39 | 40 | ChronicleLogReader reader = new ChronicleLogReader(args[i].trim(), wt); 41 | 42 | reader.processLogs(ChronicleLogReader::printf, false); 43 | 44 | } else { 45 | System.err.println("\nUsage: ChroniCat [-w ] "); 46 | System.err.println(" - wire format, default BINARY_LIGHT"); 47 | System.err.println(" - base path of Chronicle Logs storage"); 48 | } 49 | } catch (Exception e) { 50 | e.printStackTrace(System.err); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /logger-tools/src/main/java/net/openhft/chronicle/logger/tools/ChroniTail.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.tools; 19 | 20 | import net.openhft.chronicle.wire.WireType; 21 | 22 | public final class ChroniTail { 23 | 24 | private ChroniTail() { 25 | } 26 | 27 | public static void main(String[] args) { 28 | try { 29 | 30 | if (args.length >= 1) { 31 | int i = 0; 32 | final WireType wt; 33 | if ("-w".equals(args[i++])) { 34 | wt = WireType.valueOf(args[i++].trim().toUpperCase()); 35 | } else { 36 | wt = WireType.BINARY_LIGHT; 37 | } 38 | 39 | ChronicleLogReader reader = new ChronicleLogReader(args[i].trim(), wt); 40 | 41 | reader.processLogs(ChronicleLogReader::printf, true); 42 | 43 | } else { 44 | System.err.println("\nUsage: ChroniTail [-w ] "); 45 | System.err.println(" - wire format, default BINARY_LIGHT"); 46 | System.err.println(" - base path of Chronicle Logs storage"); 47 | } 48 | } catch (Exception e) { 49 | e.printStackTrace(System.err); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /logger-tools/src/main/java/net/openhft/chronicle/logger/tools/ChronicleLogProcessor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.tools; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogLevel; 21 | import org.jetbrains.annotations.Nullable; 22 | 23 | public interface ChronicleLogProcessor { 24 | void process( 25 | final long timestamp, 26 | final ChronicleLogLevel level, 27 | final String loggerName, 28 | final String threadName, 29 | final String message, 30 | @Nullable final Throwable throwable, 31 | final Object[] args); 32 | } 33 | -------------------------------------------------------------------------------- /logger-tools/src/main/java/net/openhft/chronicle/logger/tools/ChronicleLogReader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2022 Chronicle Software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.tools; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogLevel; 21 | import net.openhft.chronicle.queue.ChronicleQueue; 22 | import net.openhft.chronicle.queue.ExcerptTailer; 23 | import net.openhft.chronicle.wire.DocumentContext; 24 | import net.openhft.chronicle.wire.Wire; 25 | import net.openhft.chronicle.wire.WireType; 26 | import org.jetbrains.annotations.NotNull; 27 | import org.jetbrains.annotations.Nullable; 28 | import org.slf4j.helpers.MessageFormatter; 29 | 30 | import java.text.SimpleDateFormat; 31 | import java.util.ArrayList; 32 | import java.util.List; 33 | 34 | /** 35 | * Generic tool allowing users to process Chronicle logs in their own way 36 | */ 37 | public class ChronicleLogReader { 38 | private static final SimpleDateFormat tsFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); 39 | private final ChronicleQueue cq; 40 | 41 | /** 42 | * Create reader with default wire type 43 | * 44 | * @param path the path to Chronicle Logs storage 45 | */ 46 | public ChronicleLogReader( 47 | @NotNull String path) { 48 | this(path, WireType.BINARY_LIGHT); 49 | } 50 | 51 | /** 52 | * @param path the path to Chronicle Logs storage 53 | * @param wireType Chronicle wire type. Must match the wire type specified in corresponding Chronicle Logger 54 | */ 55 | public ChronicleLogReader( 56 | @NotNull String path, 57 | @NotNull WireType wireType) { 58 | cq = ChronicleQueue.singleBuilder(path).wireType(wireType).build(); 59 | } 60 | 61 | /** 62 | * Simple {@link ChronicleLogProcessor} implementation. Prints formatted message to stdout 63 | */ 64 | public static void printf( 65 | long timestamp, 66 | ChronicleLogLevel level, 67 | String loggerName, 68 | String threadName, 69 | String message, 70 | @Nullable Throwable throwable, 71 | Object[] args) { 72 | 73 | message = MessageFormatter.arrayFormat(message, args).getMessage(); 74 | 75 | if (throwable == null) { 76 | System.out.printf("%s [%s] [%s] [%s] %s%n", 77 | tsFormat.format(timestamp), 78 | level.toString(), 79 | threadName, 80 | loggerName, 81 | message); 82 | 83 | } else { 84 | System.out.printf("%s [%s] [%s] [%s] %s%n%s%n", 85 | tsFormat.format(timestamp), 86 | level.toString(), 87 | threadName, 88 | loggerName, 89 | message, 90 | throwable.toString()); 91 | } 92 | } 93 | 94 | /** 95 | * Decode logs 96 | * 97 | * @param processor user-provided processor called for each log message 98 | * @param waitForIt whether to wait for more data or stop after EOF reached 99 | */ 100 | public void processLogs(@NotNull ChronicleLogProcessor processor, boolean waitForIt) { 101 | ExcerptTailer tailer = cq.createTailer(); 102 | for (; ; ) { 103 | try (DocumentContext dc = tailer.readingDocument()) { 104 | Wire wire = dc.wire(); 105 | if (wire == null) 106 | if (waitForIt) { 107 | try { 108 | Thread.sleep(50L); 109 | } catch (InterruptedException ignored) { 110 | 111 | } 112 | continue; 113 | } else { 114 | break; 115 | } 116 | 117 | long timestamp = wire.read("ts").int64(); 118 | ChronicleLogLevel level = wire.read("level").asEnum(ChronicleLogLevel.class); 119 | String threadName = wire.read("threadName").text(); 120 | String loggerName = wire.read("loggerName").text(); 121 | String message = wire.read("message").text(); 122 | Throwable th = wire.hasMore() ? wire.read("throwable").throwable(false) : null; 123 | List argsL = new ArrayList<>(); 124 | if (wire.hasMore()) { 125 | wire.read("args").sequence(argsL, (l, vi) -> { 126 | while (vi.hasNextSequenceItem()) { 127 | l.add(vi.object(Object.class)); 128 | } 129 | }); 130 | } 131 | Object[] args = argsL.toArray(new Object[argsL.size()]); 132 | processor.process(timestamp, level, threadName, loggerName, message, th, args); 133 | } 134 | } 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /logger-tools/src/main/java/net/openhft/chronicle/logger/tools/internal/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This package and any and all sub-packages contains strictly internal classes for this Chronicle library. 3 | * Internal classes shall never be used directly. 4 | * 5 | * Specifically, the following actions (including, but not limited to) are not allowed 6 | * on internal classes and packages: 7 | * 8 | * Casting to 9 | * Reflection of any kind 10 | * Explicit Serialize/deserialize 11 | * 12 | * 13 | * The classes in this package and any sub-package are subject to 14 | * changes at any time for any reason. 15 | */ 16 | package net.openhft.chronicle.logger.tools.internal; 17 | -------------------------------------------------------------------------------- /logger-tools/src/test/java/net/openhft/chronicle/logger/tools/ChronicleLogReaderTest.java: -------------------------------------------------------------------------------- 1 | package net.openhft.chronicle.logger.tools; 2 | 3 | import net.openhft.chronicle.core.OS; 4 | import net.openhft.chronicle.core.util.Time; 5 | import net.openhft.chronicle.wire.WireType; 6 | import org.junit.Before; 7 | import org.junit.Test; 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | 11 | public class ChronicleLogReaderTest { 12 | @Before 13 | public void setup() { 14 | System.setProperty( 15 | "logback.configurationFile", 16 | System.getProperty("resources.path") 17 | + "/logback-chronicle-binary-appender.xml"); 18 | } 19 | 20 | @Test 21 | public void readTest() { 22 | final Logger logger = LoggerFactory.getLogger("binary-chronicle"); 23 | logger.info("test {} {} {}", 1, 100L, 100.123D); 24 | logger.info("test {} {} {}", 2, 100L, 100.123D); 25 | logger.info("test {} {} {}", 3, 100L, 100.123D); 26 | 27 | ChronicleLogReader reader = new ChronicleLogReader(OS.getTarget() + "/chronicle-logback/binary-chronicle" + Time.uniqueId(), WireType.BINARY_LIGHT); 28 | reader.processLogs(ChronicleLogReader::printf, false); 29 | 30 | //ChroniCat.main(new String[] {OS.getTarget() + "/chronicle-logback/binary-chronicle"}); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /logger-tools/src/test/resources/logback-chronicle-binary-appender.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 22 | 23 | 25 | 26 | %d %contextName [%t] %level %logger{36} - %msg%n 27 | 28 | 29 | 31 | ${java.io.tmpdir}/chronicle-logback/binary-chronicle 32 | false 33 | false 34 | 35 | 128 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 4.0.0 22 | 23 | 24 | net.openhft 25 | java-parent-pom 26 | 1.27ea1 27 | 28 | 29 | 30 | chronicle-logger 31 | 4.27ea2-SNAPSHOT 32 | pom 33 | 34 | OpenHFT/Chronicle-Logger 35 | OpenHFT :: High Performance Logging 36 | 37 | 38 | 39 | 40 | net.openhft 41 | third-party-bom 42 | 3.27ea2 43 | pom 44 | import 45 | 46 | 47 | 48 | net.openhft 49 | chronicle-bom 50 | 2.27ea-SNAPSHOT 51 | pom 52 | import 53 | 54 | 55 | 56 | 57 | net.openhft 58 | chronicle-logger-core 59 | ${project.version} 60 | 61 | 62 | 63 | net.openhft 64 | chronicle-logger-logback 65 | ${project.version} 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | net.openhft 75 | chronicle-core 76 | 77 | 78 | 79 | net.openhft 80 | chronicle-bytes 81 | 82 | 83 | 84 | net.openhft 85 | chronicle-queue 86 | 87 | 88 | 89 | org.jetbrains 90 | annotations 91 | 92 | 93 | 94 | 95 | org.apache.commons 96 | commons-lang3 97 | test 98 | 99 | 100 | junit 101 | junit 102 | test 103 | 104 | 105 | 106 | 107 | org.openjdk.jmh 108 | jmh-core 109 | test 110 | 111 | 112 | org.openjdk.jmh 113 | jmh-core-benchmarks 114 | test 115 | 116 | 117 | 118 | 119 | logger-core 120 | logger-jul 121 | logger-jcl 122 | logger-slf4j 123 | logger-slf4j-2 124 | logger-logback 125 | logger-log4j-1 126 | logger-log4j-2 127 | logger-tools 128 | benchmark 129 | 130 | 131 | 132 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 133 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 134 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 135 | master 136 | 137 | 138 | 139 | 140 | --------------------------------------------------------------------------------
Simple implementation of Logger that sends all enabled slf4j messages, 32 | * for all defined loggers, to one or more VanillaChronicle.. 33 | *
34 | * To configure this sl4j binding you need to specify the location of a properties 35 | * files via system properties: 36 | * {@code -Dchronicle.logger.properties=${pathOfYourPropertiesFile}} 37 | *
38 | * The following system properties are supported to configure the behavior of this 39 | * logger: 40 | *
13 | * The classes in this package and any sub-package are subject to 14 | * changes at any time for any reason. 15 | */ 16 | package net.openhft.chronicle.logger.slf4j2.internal; 17 | -------------------------------------------------------------------------------- /logger-slf4j-2/src/main/java/org/slf4j/impl/ChronicleServiceProvider.java: -------------------------------------------------------------------------------- 1 | package org.slf4j.impl; 2 | 3 | import net.openhft.chronicle.logger.slf4j2.ChronicleLoggerFactory; 4 | import org.slf4j.ILoggerFactory; 5 | import org.slf4j.IMarkerFactory; 6 | import org.slf4j.helpers.BasicMarkerFactory; 7 | import org.slf4j.helpers.NOPMDCAdapter; 8 | import org.slf4j.spi.MDCAdapter; 9 | import org.slf4j.spi.SLF4JServiceProvider; 10 | 11 | public class ChronicleServiceProvider implements SLF4JServiceProvider { 12 | 13 | /** 14 | * Declare the version of the SLF4J API this implementation is compiled against. 15 | * The value of this field is modified with each major release. 16 | */ 17 | // to avoid constant folding by the compiler, this field must *not* be final 18 | public static String REQUESTED_API_VERSION = "2.0.99"; // !final 19 | 20 | public ChronicleServiceProvider() {} 21 | /** 22 | * The ILoggerFactory instance returned by the {@link #getLoggerFactory} 23 | * method should always be the same object 24 | */ 25 | private ILoggerFactory loggerFactory; 26 | 27 | private IMarkerFactory markerFactory; 28 | private MDCAdapter mdcAdapter; 29 | 30 | @Override 31 | public ILoggerFactory getLoggerFactory() { 32 | return loggerFactory; 33 | } 34 | 35 | @Override 36 | public IMarkerFactory getMarkerFactory() { 37 | return markerFactory; 38 | } 39 | 40 | @Override 41 | public MDCAdapter getMDCAdapter() { 42 | return mdcAdapter; 43 | } 44 | 45 | @Override 46 | public String getRequestedApiVersion() { 47 | return REQUESTED_API_VERSION; 48 | } 49 | 50 | @Override 51 | public void initialize() { 52 | loggerFactory = new ChronicleLoggerFactory(); 53 | markerFactory = new BasicMarkerFactory(); 54 | mdcAdapter = new NOPMDCAdapter(); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /logger-slf4j-2/src/main/java/org/slf4j/impl/OutputChoice.java: -------------------------------------------------------------------------------- 1 | package org.slf4j.impl; 2 | 3 | import java.io.PrintStream; 4 | 5 | /** 6 | * This class encapsulates the user's choice of output target. 7 | * 8 | * @author Ceki Gülcü 9 | * 10 | */ 11 | class OutputChoice { 12 | 13 | enum OutputChoiceType { 14 | SYS_OUT, CACHED_SYS_OUT, SYS_ERR, CACHED_SYS_ERR, FILE; 15 | } 16 | 17 | final OutputChoiceType outputChoiceType; 18 | final PrintStream targetPrintStream; 19 | 20 | OutputChoice(OutputChoiceType outputChoiceType) { 21 | if (outputChoiceType == OutputChoiceType.FILE) { 22 | throw new IllegalArgumentException(); 23 | } 24 | this.outputChoiceType = outputChoiceType; 25 | if (outputChoiceType == OutputChoiceType.CACHED_SYS_OUT) { 26 | this.targetPrintStream = System.out; 27 | } else if (outputChoiceType == OutputChoiceType.CACHED_SYS_ERR) { 28 | this.targetPrintStream = System.err; 29 | } else { 30 | this.targetPrintStream = null; 31 | } 32 | } 33 | 34 | OutputChoice(PrintStream printStream) { 35 | this.outputChoiceType = OutputChoiceType.FILE; 36 | this.targetPrintStream = printStream; 37 | } 38 | 39 | PrintStream getTargetPrintStream() { 40 | switch (outputChoiceType) { 41 | case SYS_OUT: 42 | return System.out; 43 | case SYS_ERR: 44 | return System.err; 45 | case CACHED_SYS_ERR: 46 | case CACHED_SYS_OUT: 47 | case FILE: 48 | return targetPrintStream; 49 | default: 50 | throw new IllegalArgumentException(); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /logger-slf4j-2/src/main/resources/META-INF/services/org.slf4j.spi.SLF4JServiceProvider: -------------------------------------------------------------------------------- 1 | org.slf4j.impl.ChronicleServiceProvider 2 | -------------------------------------------------------------------------------- /logger-slf4j-2/src/test/java/net/openhft/chronicle/logger/slf4j2/ChronicleLoggingConfigTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.slf4j2; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogConfig; 21 | import org.junit.Test; 22 | 23 | import static org.junit.Assert.assertNotNull; 24 | 25 | public class ChronicleLoggingConfigTest { 26 | @Test 27 | public void testLoadClasspathIndexed() { 28 | System.setProperty("chronicle.logger.properties", "chronicle.logger.properties"); 29 | assertLoadsValidConfig(); 30 | } 31 | 32 | private void assertLoadsValidConfig() { 33 | ChronicleLogConfig config = ChronicleLogConfig.load(); 34 | assertNotNull("unable to load config", config); 35 | assertNotNull("is not a valid config", config.getAppenderConfig()); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /logger-slf4j-2/src/test/java/net/openhft/chronicle/logger/slf4j2/Slf4jChronicleConfigurationTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.slf4j2; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogConfig; 21 | import net.openhft.chronicle.logger.ChronicleLogLevel; 22 | import org.junit.Test; 23 | 24 | import java.io.File; 25 | import java.util.Properties; 26 | 27 | import static org.junit.Assert.assertEquals; 28 | import static org.junit.Assert.assertNotNull; 29 | 30 | public class Slf4jChronicleConfigurationTest extends Slf4jTestBase { 31 | 32 | @Test 33 | public void testLoadProperties() { 34 | final String cfgPath = "chronicle.logger.properties"; 35 | final ChronicleLogConfig cfg = ChronicleLogConfig.load(cfgPath); 36 | 37 | assertNotNull(cfg); 38 | 39 | assertEquals( 40 | new File(basePath("root")), 41 | new File(cfg.getString(ChronicleLogConfig.KEY_PATH))); 42 | assertEquals( 43 | ChronicleLogLevel.DEBUG.toString(), 44 | cfg.getString(ChronicleLogConfig.KEY_LEVEL).toUpperCase()); 45 | assertEquals("false", cfg.getString(ChronicleLogConfig.KEY_APPEND)); 46 | assertEquals( 47 | new File(basePath("logger_1")), 48 | new File(cfg.getString("logger_1", ChronicleLogConfig.KEY_PATH))); 49 | assertEquals( 50 | ChronicleLogLevel.INFO.toString(), 51 | cfg.getString("logger_1", ChronicleLogConfig.KEY_LEVEL).toUpperCase()); 52 | assertEquals( 53 | ChronicleLogLevel.DEBUG.toString(), 54 | cfg.getString("readwrite", ChronicleLogConfig.KEY_LEVEL).toUpperCase()); 55 | } 56 | 57 | @Test 58 | public void testLoadConfig() { 59 | final Properties properties = new Properties(); 60 | properties.setProperty("chronicle.logger.root.cfg.blockSize", "256"); 61 | 62 | final ChronicleLogConfig clc = ChronicleLogConfig.load(properties); 63 | assertNotNull(clc.getAppenderConfig()); 64 | 65 | assertEquals(256, clc.getAppenderConfig().getBlockSize()); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /logger-slf4j-2/src/test/java/net/openhft/chronicle/logger/slf4j2/Slf4jChronicleLoggerPerfTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.slf4j2; 19 | 20 | import net.openhft.chronicle.core.io.IOTools; 21 | import org.apache.commons.lang3.StringUtils; 22 | import org.junit.After; 23 | import org.junit.Before; 24 | import org.junit.Ignore; 25 | import org.junit.Test; 26 | import org.slf4j.Logger; 27 | import org.slf4j.LoggerFactory; 28 | 29 | import java.util.concurrent.ExecutorService; 30 | import java.util.concurrent.Executors; 31 | import java.util.concurrent.TimeUnit; 32 | 33 | @Ignore 34 | public class Slf4jChronicleLoggerPerfTest extends Slf4jTestBase { 35 | 36 | // ************************************************************************* 37 | // 38 | // ************************************************************************* 39 | 40 | @Before 41 | public void setUp() { 42 | System.setProperty( 43 | "chronicle.logger.properties", 44 | "chronicle.logger.perf.properties"); 45 | 46 | getChronicleLoggerFactory().reload(); 47 | } 48 | 49 | @After 50 | public void tearDown() { 51 | IOTools.deleteDirWithFiles(basePath()); 52 | } 53 | 54 | // ************************************************************************* 55 | // Single Thread 56 | // ************************************************************************* 57 | 58 | @Test 59 | public void testSingleThreadLogging1() { 60 | Thread.currentThread().setName("perf-plain"); 61 | 62 | final String testId = "perf-chronicle"; 63 | final Logger clogger = LoggerFactory.getLogger(testId); 64 | final long items = 1000000; 65 | 66 | warmup(clogger); 67 | 68 | for (int s = 64; s <= 1024; s += 64) { 69 | final String staticStr = StringUtils.leftPad("", s, 'X'); 70 | 71 | long cStart1 = System.nanoTime(); 72 | 73 | for (int i = 1; i <= items; i++) { 74 | clogger.info(staticStr); 75 | } 76 | 77 | long cEnd1 = System.nanoTime(); 78 | 79 | System.out.printf("items=%03d size=%04d => chronology=%.3f ms, chronology-average=%.3f us\n", 80 | items, 81 | staticStr.length(), 82 | (cEnd1 - cStart1) / 1e6, 83 | (cEnd1 - cStart1) / items / 1e3); 84 | } 85 | } 86 | 87 | @Test 88 | public void testSingleThreadLogging2() { 89 | Thread.currentThread().setName("perf-plain"); 90 | 91 | final String testId = "perf-chronicle"; 92 | final Logger clogger = LoggerFactory.getLogger(testId); 93 | final long items = 1000000; 94 | final String strFmt = StringUtils.leftPad("> v1={}, v2={}, v3={}", 32, 'X'); 95 | 96 | warmup(clogger); 97 | 98 | for (int n = 0; n < 10; n++) { 99 | long cStart1 = System.nanoTime(); 100 | 101 | for (int i = 1; i <= items; i++) { 102 | clogger.info(strFmt, i, i * 10, i / 16); 103 | } 104 | 105 | long cEnd1 = System.nanoTime(); 106 | 107 | System.out.printf("items=%03d => chronology=%.3f ms, chronology-average=%.3f us\n", 108 | items, 109 | (cEnd1 - cStart1) / 1e6, 110 | (cEnd1 - cStart1) / items / 1e3); 111 | } 112 | } 113 | 114 | // ************************************************************************* 115 | // Multi Thread 116 | // ************************************************************************* 117 | 118 | @Test 119 | public void testMultiThreadLogging() throws InterruptedException { 120 | warmup(LoggerFactory.getLogger("perf-chronicle")); 121 | 122 | final int RUNS = 1000000; 123 | final int THREADS = 10; 124 | 125 | for (int size : new int[]{64, 128, 256}) { 126 | { 127 | final long start = System.nanoTime(); 128 | 129 | ExecutorService es = Executors.newFixedThreadPool(THREADS); 130 | for (int t = 0; t < THREADS; t++) { 131 | es.submit(new RunnableLogger(RUNS, size, "perf-chronicle")); 132 | } 133 | 134 | es.shutdown(); 135 | es.awaitTermination(5, TimeUnit.SECONDS); 136 | 137 | final long time = System.nanoTime() - start; 138 | 139 | System.out.printf("ChronicleLog.MT (runs=%d, min size=%03d, elapsed=%.3f ms) took an average of %.3f us per entry\n", 140 | RUNS, 141 | size, 142 | time / 1e6, 143 | time / 1e3 / (RUNS * THREADS) 144 | ); 145 | } 146 | } 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /logger-slf4j-2/src/test/java/net/openhft/chronicle/logger/slf4j2/Slf4jTestBase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.slf4j2; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogLevel; 21 | import net.openhft.chronicle.logger.slf4j2.ChronicleLoggerFactory; 22 | import org.apache.commons.lang3.StringUtils; 23 | import org.slf4j.Logger; 24 | import org.slf4j.LoggerFactory; 25 | import org.slf4j.impl.ChronicleServiceProvider; 26 | 27 | class Slf4jTestBase { 28 | 29 | // ************************************************************************* 30 | // 31 | // ************************************************************************* 32 | 33 | static final ChronicleLogLevel[] LOG_LEVELS = ChronicleLogLevel.values(); 34 | 35 | static String basePath() { 36 | String path = System.getProperty("java.io.tmpdir"); 37 | String sep = System.getProperty("file.separator"); 38 | 39 | if (!path.endsWith(sep)) { 40 | path += sep; 41 | } 42 | 43 | return path + "chronicle-slf4j"; 44 | } 45 | 46 | static String basePath(String loggerName) { 47 | return basePath() 48 | + System.getProperty("file.separator") 49 | + loggerName; 50 | } 51 | 52 | static void log(Logger logger, ChronicleLogLevel level, String fmt, Object... args) { 53 | switch (level) { 54 | case TRACE: 55 | logger.trace(fmt, args); 56 | break; 57 | 58 | case DEBUG: 59 | logger.debug(fmt, args); 60 | break; 61 | 62 | case INFO: 63 | logger.info(fmt, args); 64 | break; 65 | 66 | case WARN: 67 | logger.warn(fmt, args); 68 | break; 69 | 70 | case ERROR: 71 | logger.error(fmt, args); 72 | break; 73 | default: 74 | throw new UnsupportedOperationException(); 75 | } 76 | } 77 | 78 | static void warmup(Logger logger) { 79 | for (int i = 0; i < 10; i++) { 80 | logger.info("warmup"); 81 | } 82 | } 83 | 84 | // ************************************************************************* 85 | // 86 | // ************************************************************************* 87 | 88 | /** 89 | * @return the ChronicleLoggerFactory singleton 90 | */ 91 | ChronicleLoggerFactory getChronicleLoggerFactory() { 92 | ChronicleServiceProvider provider = new ChronicleServiceProvider(); 93 | provider.initialize(); 94 | return (ChronicleLoggerFactory) provider.getLoggerFactory(); 95 | } 96 | 97 | // ************************************************************************* 98 | // 99 | // ************************************************************************* 100 | 101 | protected final class RunnableLogger implements Runnable { 102 | private final Logger logger; 103 | private final int runs; 104 | private final String fmt; 105 | private final String fmtBase = " > val1={}, val2={}, val3={}"; 106 | 107 | public RunnableLogger(int runs, int pad, String loggerName) { 108 | this.logger = LoggerFactory.getLogger(loggerName); 109 | this.runs = runs; 110 | this.fmt = StringUtils.rightPad(fmtBase, pad + fmtBase.length() - (4 + 8 + 8), "X"); 111 | } 112 | 113 | @Override 114 | public void run() { 115 | for (int i = 0; i < this.runs; i++) { 116 | this.logger.info(fmt, i, i * 7L, i / 16.0); 117 | } 118 | } 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /logger-slf4j-2/src/test/resources/chronicle.logger.perf.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2014-2017 Chronicle Software 3 | # 4 | # https://chronicle.software 5 | # 6 | # This program is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License 16 | # along with this program. If not, see . 17 | # 18 | 19 | chronicle.logger.base = ${java.io.tmpdir}/chronicle-slf4j 20 | 21 | chronicle.logger.root.path = ${chronicle.logger.base}/perf 22 | chronicle.logger.root.level = debug 23 | chronicle.logger.root.append = false 24 | -------------------------------------------------------------------------------- /logger-slf4j-2/src/test/resources/chronicle.logger.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2014-2017 Chronicle Software 3 | # 4 | # https://chronicle.software 5 | # 6 | # This program is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License 16 | # along with this program. If not, see . 17 | # 18 | 19 | ################################################################################ 20 | # Common 21 | ################################################################################ 22 | 23 | chronicle.logger.base = ${java.io.tmpdir}/chronicle-slf4j 24 | chronicle.logger.root.path = ${chronicle.logger.base}/root 25 | chronicle.logger.root.level = debug 26 | chronicle.logger.root.append = false 27 | 28 | ################################################################################ 29 | # Loggers 30 | ################################################################################ 31 | 32 | # logger : Logger1 33 | chronicle.logger.logger_1.path = ${chronicle.logger.base}/logger_1 34 | chronicle.logger.logger_1.level = info 35 | 36 | # logger : impl 37 | chronicle.logger.readwrite.path = ${chronicle.logger.base}/readwrite 38 | -------------------------------------------------------------------------------- /logger-slf4j/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 22 | 23 | 4.0.0 24 | 25 | 26 | net.openhft 27 | chronicle-logger 28 | 4.27ea2-SNAPSHOT 29 | ../pom.xml 30 | 31 | 32 | OpenHFT/Chronicle-Logger/logger-slf4j 33 | chronicle-logger-slf4j 34 | bundle 35 | 36 | 37 | 38 | net.openhft 39 | chronicle-logger-core 40 | 41 | 42 | 43 | 44 | org.slf4j 45 | slf4j-api 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | org.apache.maven.plugins 54 | maven-surefire-plugin 55 | 56 | 57 | **/*PerfTest.java 58 | 59 | 60 | ${project.build.directory} 61 | 62 | 63 | 64 | 72 | 73 | org.apache.servicemix.tooling 74 | depends-maven-plugin 75 | 76 | 77 | generate-depends-file 78 | 79 | generate-depends-file 80 | 81 | 82 | 83 | 84 | 85 | org.apache.felix 86 | maven-bundle-plugin 87 | true 88 | 89 | 90 | ${project.groupId}.${project.artifactId} 91 | OpenHFT :: ${project.artifactId} 92 | ${project.version} 93 | net.openhft.chronicle.logger.slf4j.* 94 | 95 | 96 | 97 | 101 | 102 | 103 | manifest 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 113 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 114 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 115 | master 116 | 117 | 118 | 119 | -------------------------------------------------------------------------------- /logger-slf4j/src/main/java/net/openhft/chronicle/logger/slf4j/ChronicleLoggerFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.slf4j; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogManager; 21 | import net.openhft.chronicle.logger.ChronicleLogWriter; 22 | import org.slf4j.ILoggerFactory; 23 | import org.slf4j.Logger; 24 | import org.slf4j.helpers.NOPLogger; 25 | import org.slf4j.impl.SimpleLogger; 26 | 27 | import java.util.Map; 28 | import java.util.concurrent.ConcurrentHashMap; 29 | 30 | /** 31 | *
13 | * The classes in this package and any sub-package are subject to 14 | * changes at any time for any reason. 15 | */ 16 | package net.openhft.chronicle.logger.slf4j.internal; 17 | -------------------------------------------------------------------------------- /logger-slf4j/src/main/java/org/slf4j/impl/OutputChoice.java: -------------------------------------------------------------------------------- 1 | package org.slf4j.impl; 2 | 3 | import java.io.PrintStream; 4 | 5 | /** 6 | * This class encapsulates the user's choice of output target. 7 | * 8 | * @author Ceki Gülcü 9 | * 10 | */ 11 | class OutputChoice { 12 | 13 | enum OutputChoiceType { 14 | SYS_OUT, CACHED_SYS_OUT, SYS_ERR, CACHED_SYS_ERR, FILE; 15 | } 16 | 17 | final OutputChoiceType outputChoiceType; 18 | final PrintStream targetPrintStream; 19 | 20 | OutputChoice(OutputChoiceType outputChoiceType) { 21 | if (outputChoiceType == OutputChoiceType.FILE) { 22 | throw new IllegalArgumentException(); 23 | } 24 | this.outputChoiceType = outputChoiceType; 25 | if (outputChoiceType == OutputChoiceType.CACHED_SYS_OUT) { 26 | this.targetPrintStream = System.out; 27 | } else if (outputChoiceType == OutputChoiceType.CACHED_SYS_ERR) { 28 | this.targetPrintStream = System.err; 29 | } else { 30 | this.targetPrintStream = null; 31 | } 32 | } 33 | 34 | OutputChoice(PrintStream printStream) { 35 | this.outputChoiceType = OutputChoiceType.FILE; 36 | this.targetPrintStream = printStream; 37 | } 38 | 39 | PrintStream getTargetPrintStream() { 40 | switch (outputChoiceType) { 41 | case SYS_OUT: 42 | return System.out; 43 | case SYS_ERR: 44 | return System.err; 45 | case CACHED_SYS_ERR: 46 | case CACHED_SYS_OUT: 47 | case FILE: 48 | return targetPrintStream; 49 | default: 50 | throw new IllegalArgumentException(); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /logger-slf4j/src/main/java/org/slf4j/impl/StaticLoggerBinder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.slf4j.impl; 19 | 20 | import net.openhft.chronicle.logger.slf4j.ChronicleLoggerFactory; 21 | import org.slf4j.ILoggerFactory; 22 | import org.slf4j.spi.LoggerFactoryBinder; 23 | 24 | public class StaticLoggerBinder implements LoggerFactoryBinder { 25 | 26 | private static final StaticLoggerBinder SINGLETON = new StaticLoggerBinder(); 27 | private static final String loggerFactoryClassStr = ChronicleLoggerFactory.class.getName(); 28 | /** 29 | * Declare the version of the SLF4J API this implementation is compiled 30 | * against. The value of this field is usually modified with each release. 31 | */ 32 | // to avoid constant folding by the compiler, this field must *not* be final 33 | public static String REQUESTED_API_VERSION = "1.7.30"; // !final 34 | /** 35 | * The ILoggerFactory instance returned by the {@link #getLoggerFactory} 36 | * method should always be the same object 37 | */ 38 | private final ILoggerFactory loggerFactory; 39 | 40 | /** 41 | * c-tor 42 | */ 43 | private StaticLoggerBinder() { 44 | loggerFactory = new ChronicleLoggerFactory(); 45 | } 46 | 47 | /** 48 | * Return the singleton of this class. 49 | * 50 | * @return the StaticLoggerBinder singleton 51 | */ 52 | public static final StaticLoggerBinder getSingleton() { 53 | return SINGLETON; 54 | } 55 | 56 | @Override 57 | public ILoggerFactory getLoggerFactory() { 58 | return loggerFactory; 59 | } 60 | 61 | @Override 62 | public String getLoggerFactoryClassStr() { 63 | return loggerFactoryClassStr; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /logger-slf4j/src/main/java/org/slf4j/impl/StaticMarkerBinder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.slf4j.impl; 19 | 20 | import org.slf4j.IMarkerFactory; 21 | import org.slf4j.helpers.BasicMarkerFactory; 22 | import org.slf4j.spi.MarkerFactoryBinder; 23 | 24 | /** 25 | * The binding of {@link org.slf4j.MarkerFactory} class with an actual instance of 26 | * {@link IMarkerFactory} is performed using information returned by this class. 27 | * 28 | * @author Ceki Gülcü 29 | */ 30 | public class StaticMarkerBinder implements MarkerFactoryBinder { 31 | 32 | /** 33 | * The unique instance of this class. 34 | */ 35 | public static final StaticMarkerBinder SINGLETON = new StaticMarkerBinder(); 36 | 37 | final IMarkerFactory markerFactory = new BasicMarkerFactory(); 38 | 39 | private StaticMarkerBinder() { 40 | } 41 | 42 | /** 43 | * Currently this method always returns an instance of 44 | * {@link BasicMarkerFactory}. 45 | */ 46 | @Override 47 | public IMarkerFactory getMarkerFactory() { 48 | return markerFactory; 49 | } 50 | 51 | /** 52 | * Currently, this method returns the class name of 53 | * {@link BasicMarkerFactory}. 54 | */ 55 | @Override 56 | public String getMarkerFactoryClassStr() { 57 | return BasicMarkerFactory.class.getName(); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /logger-slf4j/src/test/java/net/openhft/chronicle/logger/slf4j/ChronicleLoggingConfigTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.slf4j; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogConfig; 21 | import org.junit.Test; 22 | 23 | import static org.junit.Assert.assertNotNull; 24 | 25 | public class ChronicleLoggingConfigTest { 26 | @Test 27 | public void testLoadClasspathIndexed() { 28 | System.setProperty("chronicle.logger.properties", "chronicle.logger.properties"); 29 | assertLoadsValidConfig(); 30 | } 31 | 32 | private void assertLoadsValidConfig() { 33 | ChronicleLogConfig config = ChronicleLogConfig.load(); 34 | assertNotNull("unable to load config", config); 35 | assertNotNull("is not a valid config", config.getAppenderConfig()); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /logger-slf4j/src/test/java/net/openhft/chronicle/logger/slf4j/Slf4jChronicleConfigurationTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.slf4j; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogConfig; 21 | import net.openhft.chronicle.logger.ChronicleLogLevel; 22 | import org.junit.Test; 23 | 24 | import java.io.File; 25 | import java.util.Properties; 26 | 27 | import static org.junit.Assert.assertEquals; 28 | import static org.junit.Assert.assertNotNull; 29 | 30 | public class Slf4jChronicleConfigurationTest extends Slf4jTestBase { 31 | 32 | @Test 33 | public void testLoadProperties() { 34 | final String cfgPath = "chronicle.logger.properties"; 35 | final ChronicleLogConfig cfg = ChronicleLogConfig.load(cfgPath); 36 | 37 | assertNotNull(cfg); 38 | 39 | assertEquals( 40 | new File(basePath("root")), 41 | new File(cfg.getString(ChronicleLogConfig.KEY_PATH))); 42 | assertEquals( 43 | ChronicleLogLevel.DEBUG.toString(), 44 | cfg.getString(ChronicleLogConfig.KEY_LEVEL).toUpperCase()); 45 | assertEquals("false", cfg.getString(ChronicleLogConfig.KEY_APPEND)); 46 | assertEquals( 47 | new File(basePath("logger_1")), 48 | new File(cfg.getString("logger_1", ChronicleLogConfig.KEY_PATH))); 49 | assertEquals( 50 | ChronicleLogLevel.INFO.toString(), 51 | cfg.getString("logger_1", ChronicleLogConfig.KEY_LEVEL).toUpperCase()); 52 | assertEquals( 53 | ChronicleLogLevel.DEBUG.toString(), 54 | cfg.getString("readwrite", ChronicleLogConfig.KEY_LEVEL).toUpperCase()); 55 | } 56 | 57 | @Test 58 | public void testLoadConfig() { 59 | final Properties properties = new Properties(); 60 | properties.setProperty("chronicle.logger.root.cfg.blockSize", "256"); 61 | 62 | final ChronicleLogConfig clc = ChronicleLogConfig.load(properties); 63 | assertNotNull(clc.getAppenderConfig()); 64 | 65 | assertEquals(256, clc.getAppenderConfig().getBlockSize()); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /logger-slf4j/src/test/java/net/openhft/chronicle/logger/slf4j/Slf4jChronicleLoggerPerfTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.slf4j; 19 | 20 | import net.openhft.chronicle.core.io.IOTools; 21 | import org.apache.commons.lang3.StringUtils; 22 | import org.junit.After; 23 | import org.junit.Before; 24 | import org.junit.Ignore; 25 | import org.junit.Test; 26 | import org.slf4j.Logger; 27 | import org.slf4j.LoggerFactory; 28 | 29 | import java.util.concurrent.ExecutorService; 30 | import java.util.concurrent.Executors; 31 | import java.util.concurrent.TimeUnit; 32 | 33 | @Ignore 34 | public class Slf4jChronicleLoggerPerfTest extends Slf4jTestBase { 35 | 36 | // ************************************************************************* 37 | // 38 | // ************************************************************************* 39 | 40 | @Before 41 | public void setUp() { 42 | System.setProperty( 43 | "chronicle.logger.properties", 44 | "chronicle.logger.perf.properties"); 45 | 46 | getChronicleLoggerFactory().reload(); 47 | } 48 | 49 | @After 50 | public void tearDown() { 51 | IOTools.deleteDirWithFiles(basePath()); 52 | } 53 | 54 | // ************************************************************************* 55 | // Single Thread 56 | // ************************************************************************* 57 | 58 | @Test 59 | public void testSingleThreadLogging1() { 60 | Thread.currentThread().setName("perf-plain"); 61 | 62 | final String testId = "perf-chronicle"; 63 | final Logger clogger = LoggerFactory.getLogger(testId); 64 | final long items = 1000000; 65 | 66 | warmup(clogger); 67 | 68 | for (int s = 64; s <= 1024; s += 64) { 69 | final String staticStr = StringUtils.leftPad("", s, 'X'); 70 | 71 | long cStart1 = System.nanoTime(); 72 | 73 | for (int i = 1; i <= items; i++) { 74 | clogger.info(staticStr); 75 | } 76 | 77 | long cEnd1 = System.nanoTime(); 78 | 79 | System.out.printf("items=%03d size=%04d => chronology=%.3f ms, chronology-average=%.3f us\n", 80 | items, 81 | staticStr.length(), 82 | (cEnd1 - cStart1) / 1e6, 83 | (cEnd1 - cStart1) / items / 1e3); 84 | } 85 | } 86 | 87 | @Test 88 | public void testSingleThreadLogging2() { 89 | Thread.currentThread().setName("perf-plain"); 90 | 91 | final String testId = "perf-chronicle"; 92 | final Logger clogger = LoggerFactory.getLogger(testId); 93 | final long items = 1000000; 94 | final String strFmt = StringUtils.leftPad("> v1={}, v2={}, v3={}", 32, 'X'); 95 | 96 | warmup(clogger); 97 | 98 | for (int n = 0; n < 10; n++) { 99 | long cStart1 = System.nanoTime(); 100 | 101 | for (int i = 1; i <= items; i++) { 102 | clogger.info(strFmt, i, i * 10, i / 16); 103 | } 104 | 105 | long cEnd1 = System.nanoTime(); 106 | 107 | System.out.printf("items=%03d => chronology=%.3f ms, chronology-average=%.3f us\n", 108 | items, 109 | (cEnd1 - cStart1) / 1e6, 110 | (cEnd1 - cStart1) / items / 1e3); 111 | } 112 | } 113 | 114 | // ************************************************************************* 115 | // Multi Thread 116 | // ************************************************************************* 117 | 118 | @Test 119 | public void testMultiThreadLogging() throws InterruptedException { 120 | warmup(LoggerFactory.getLogger("perf-chronicle")); 121 | 122 | final int RUNS = 1000000; 123 | final int THREADS = 10; 124 | 125 | for (int size : new int[]{64, 128, 256}) { 126 | { 127 | final long start = System.nanoTime(); 128 | 129 | ExecutorService es = Executors.newFixedThreadPool(THREADS); 130 | for (int t = 0; t < THREADS; t++) { 131 | es.submit(new RunnableLogger(RUNS, size, "perf-chronicle")); 132 | } 133 | 134 | es.shutdown(); 135 | es.awaitTermination(5, TimeUnit.SECONDS); 136 | 137 | final long time = System.nanoTime() - start; 138 | 139 | System.out.printf("ChronicleLog.MT (runs=%d, min size=%03d, elapsed=%.3f ms) took an average of %.3f us per entry\n", 140 | RUNS, 141 | size, 142 | time / 1e6, 143 | time / 1e3 / (RUNS * THREADS) 144 | ); 145 | } 146 | } 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /logger-slf4j/src/test/java/net/openhft/chronicle/logger/slf4j/Slf4jTestBase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.slf4j; 19 | 20 | import net.openhft.chronicle.core.OS; 21 | import net.openhft.chronicle.core.util.Time; 22 | import net.openhft.chronicle.logger.ChronicleLogLevel; 23 | import org.apache.commons.lang3.StringUtils; 24 | import org.slf4j.Logger; 25 | import org.slf4j.LoggerFactory; 26 | import org.slf4j.impl.StaticLoggerBinder; 27 | 28 | class Slf4jTestBase { 29 | 30 | // ************************************************************************* 31 | // 32 | // ************************************************************************* 33 | 34 | static final ChronicleLogLevel[] LOG_LEVELS = ChronicleLogLevel.values(); 35 | 36 | static String basePath() { 37 | String path = System.getProperty("java.io.tmpdir"); 38 | String sep = System.getProperty("file.separator"); 39 | 40 | if (!path.endsWith(sep)) { 41 | path += sep; 42 | } 43 | 44 | return path + "chronicle-slf4j"; 45 | } 46 | 47 | static String basePath(String loggerName) { 48 | return basePath() 49 | + System.getProperty("file.separator") 50 | + loggerName; 51 | } 52 | 53 | static void log(Logger logger, ChronicleLogLevel level, String fmt, Object... args) { 54 | switch (level) { 55 | case TRACE: 56 | logger.trace(fmt, args); 57 | break; 58 | 59 | case DEBUG: 60 | logger.debug(fmt, args); 61 | break; 62 | 63 | case INFO: 64 | logger.info(fmt, args); 65 | break; 66 | 67 | case WARN: 68 | logger.warn(fmt, args); 69 | break; 70 | 71 | case ERROR: 72 | logger.error(fmt, args); 73 | break; 74 | default: 75 | throw new UnsupportedOperationException(); 76 | } 77 | } 78 | 79 | static void warmup(Logger logger) { 80 | for (int i = 0; i < 10; i++) { 81 | logger.info("warmup"); 82 | } 83 | } 84 | 85 | // ************************************************************************* 86 | // 87 | // ************************************************************************* 88 | 89 | /** 90 | * @return the ChronicleLoggerFactory singleton 91 | */ 92 | ChronicleLoggerFactory getChronicleLoggerFactory() { 93 | return (ChronicleLoggerFactory) StaticLoggerBinder.getSingleton().getLoggerFactory(); 94 | } 95 | 96 | // ************************************************************************* 97 | // 98 | // ************************************************************************* 99 | 100 | protected final class RunnableLogger implements Runnable { 101 | private final Logger logger; 102 | private final int runs; 103 | private final String fmt; 104 | private final String fmtBase = " > val1={}, val2={}, val3={}"; 105 | 106 | public RunnableLogger(int runs, int pad, String loggerName) { 107 | this.logger = LoggerFactory.getLogger(loggerName); 108 | this.runs = runs; 109 | this.fmt = StringUtils.rightPad(fmtBase, pad + fmtBase.length() - (4 + 8 + 8), "X"); 110 | } 111 | 112 | @Override 113 | public void run() { 114 | for (int i = 0; i < this.runs; i++) { 115 | this.logger.info(fmt, i, i * 7L, i / 16.0); 116 | } 117 | } 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /logger-slf4j/src/test/resources/chronicle.logger.perf.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2014-2017 Chronicle Software 3 | # 4 | # https://chronicle.software 5 | # 6 | # This program is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License 16 | # along with this program. If not, see . 17 | # 18 | 19 | chronicle.logger.base = ${java.io.tmpdir}/chronicle-slf4j 20 | 21 | chronicle.logger.root.path = ${chronicle.logger.base}/perf 22 | chronicle.logger.root.level = debug 23 | chronicle.logger.root.append = false 24 | -------------------------------------------------------------------------------- /logger-slf4j/src/test/resources/chronicle.logger.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2014-2017 Chronicle Software 3 | # 4 | # https://chronicle.software 5 | # 6 | # This program is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License 16 | # along with this program. If not, see . 17 | # 18 | 19 | ################################################################################ 20 | # Common 21 | ################################################################################ 22 | 23 | chronicle.logger.base = ${java.io.tmpdir}/chronicle-slf4j 24 | chronicle.logger.root.path = ${chronicle.logger.base}/root 25 | chronicle.logger.root.level = debug 26 | chronicle.logger.root.append = false 27 | 28 | ################################################################################ 29 | # Loggers 30 | ################################################################################ 31 | 32 | # logger : Logger1 33 | chronicle.logger.logger_1.path = ${chronicle.logger.base}/logger_1 34 | chronicle.logger.logger_1.level = info 35 | 36 | # logger : impl 37 | chronicle.logger.readwrite.path = ${chronicle.logger.base}/readwrite 38 | -------------------------------------------------------------------------------- /logger-tools/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 22 | 23 | 4.0.0 24 | 25 | 26 | net.openhft 27 | chronicle-logger 28 | 4.27ea2-SNAPSHOT 29 | ../pom.xml 30 | 31 | 32 | OpenHFT/Chronicle-Logger/logger-tools 33 | chronicle-logger-tools 34 | bundle 35 | 36 | 37 | 38 | net.openhft 39 | chronicle-logger-core 40 | 41 | 42 | 43 | net.openhft 44 | chronicle-wire 45 | 46 | 47 | 48 | 49 | org.slf4j 50 | slf4j-api 51 | 52 | 53 | 54 | 55 | net.openhft 56 | chronicle-logger-logback 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | org.apache.maven.plugins 65 | maven-surefire-plugin 66 | 67 | 1 68 | false 69 | 70 | **/*PerfTest.java 71 | 72 | 73 | ${project.build.directory} 74 | 75 | 76 | 77 | 85 | 86 | org.apache.servicemix.tooling 87 | depends-maven-plugin 88 | 89 | 90 | generate-depends-file 91 | 92 | generate-depends-file 93 | 94 | 95 | 96 | 97 | 98 | org.apache.felix 99 | maven-bundle-plugin 100 | true 101 | 102 | 103 | ${project.groupId}.${project.artifactId} 104 | OpenHFT :: ${project.artifactId} 105 | ${project.version} 106 | net.openhft.chronicle.logger.tools.* 107 | 108 | 109 | 110 | 114 | 115 | 116 | manifest 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 126 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 127 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 128 | master 129 | 130 | 131 | 132 | -------------------------------------------------------------------------------- /logger-tools/src/main/java/net/openhft/chronicle/logger/tools/ChroniCat.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.tools; 19 | 20 | import net.openhft.chronicle.wire.WireType; 21 | 22 | public final class ChroniCat { 23 | 24 | private ChroniCat() { 25 | } 26 | 27 | public static void main(String[] args) { 28 | try { 29 | 30 | if (args.length >= 1) { 31 | int i = 0; 32 | final WireType wt; 33 | if ("-w".equals(args[i])) { 34 | wt = WireType.valueOf(args[++i].trim().toUpperCase()); 35 | i++; 36 | } else { 37 | wt = WireType.BINARY_LIGHT; 38 | } 39 | 40 | ChronicleLogReader reader = new ChronicleLogReader(args[i].trim(), wt); 41 | 42 | reader.processLogs(ChronicleLogReader::printf, false); 43 | 44 | } else { 45 | System.err.println("\nUsage: ChroniCat [-w ] "); 46 | System.err.println(" - wire format, default BINARY_LIGHT"); 47 | System.err.println(" - base path of Chronicle Logs storage"); 48 | } 49 | } catch (Exception e) { 50 | e.printStackTrace(System.err); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /logger-tools/src/main/java/net/openhft/chronicle/logger/tools/ChroniTail.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.tools; 19 | 20 | import net.openhft.chronicle.wire.WireType; 21 | 22 | public final class ChroniTail { 23 | 24 | private ChroniTail() { 25 | } 26 | 27 | public static void main(String[] args) { 28 | try { 29 | 30 | if (args.length >= 1) { 31 | int i = 0; 32 | final WireType wt; 33 | if ("-w".equals(args[i++])) { 34 | wt = WireType.valueOf(args[i++].trim().toUpperCase()); 35 | } else { 36 | wt = WireType.BINARY_LIGHT; 37 | } 38 | 39 | ChronicleLogReader reader = new ChronicleLogReader(args[i].trim(), wt); 40 | 41 | reader.processLogs(ChronicleLogReader::printf, true); 42 | 43 | } else { 44 | System.err.println("\nUsage: ChroniTail [-w ] "); 45 | System.err.println(" - wire format, default BINARY_LIGHT"); 46 | System.err.println(" - base path of Chronicle Logs storage"); 47 | } 48 | } catch (Exception e) { 49 | e.printStackTrace(System.err); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /logger-tools/src/main/java/net/openhft/chronicle/logger/tools/ChronicleLogProcessor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 chronicle.software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.tools; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogLevel; 21 | import org.jetbrains.annotations.Nullable; 22 | 23 | public interface ChronicleLogProcessor { 24 | void process( 25 | final long timestamp, 26 | final ChronicleLogLevel level, 27 | final String loggerName, 28 | final String threadName, 29 | final String message, 30 | @Nullable final Throwable throwable, 31 | final Object[] args); 32 | } 33 | -------------------------------------------------------------------------------- /logger-tools/src/main/java/net/openhft/chronicle/logger/tools/ChronicleLogReader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2022 Chronicle Software 3 | * 4 | * https://chronicle.software 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.openhft.chronicle.logger.tools; 19 | 20 | import net.openhft.chronicle.logger.ChronicleLogLevel; 21 | import net.openhft.chronicle.queue.ChronicleQueue; 22 | import net.openhft.chronicle.queue.ExcerptTailer; 23 | import net.openhft.chronicle.wire.DocumentContext; 24 | import net.openhft.chronicle.wire.Wire; 25 | import net.openhft.chronicle.wire.WireType; 26 | import org.jetbrains.annotations.NotNull; 27 | import org.jetbrains.annotations.Nullable; 28 | import org.slf4j.helpers.MessageFormatter; 29 | 30 | import java.text.SimpleDateFormat; 31 | import java.util.ArrayList; 32 | import java.util.List; 33 | 34 | /** 35 | * Generic tool allowing users to process Chronicle logs in their own way 36 | */ 37 | public class ChronicleLogReader { 38 | private static final SimpleDateFormat tsFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); 39 | private final ChronicleQueue cq; 40 | 41 | /** 42 | * Create reader with default wire type 43 | * 44 | * @param path the path to Chronicle Logs storage 45 | */ 46 | public ChronicleLogReader( 47 | @NotNull String path) { 48 | this(path, WireType.BINARY_LIGHT); 49 | } 50 | 51 | /** 52 | * @param path the path to Chronicle Logs storage 53 | * @param wireType Chronicle wire type. Must match the wire type specified in corresponding Chronicle Logger 54 | */ 55 | public ChronicleLogReader( 56 | @NotNull String path, 57 | @NotNull WireType wireType) { 58 | cq = ChronicleQueue.singleBuilder(path).wireType(wireType).build(); 59 | } 60 | 61 | /** 62 | * Simple {@link ChronicleLogProcessor} implementation. Prints formatted message to stdout 63 | */ 64 | public static void printf( 65 | long timestamp, 66 | ChronicleLogLevel level, 67 | String loggerName, 68 | String threadName, 69 | String message, 70 | @Nullable Throwable throwable, 71 | Object[] args) { 72 | 73 | message = MessageFormatter.arrayFormat(message, args).getMessage(); 74 | 75 | if (throwable == null) { 76 | System.out.printf("%s [%s] [%s] [%s] %s%n", 77 | tsFormat.format(timestamp), 78 | level.toString(), 79 | threadName, 80 | loggerName, 81 | message); 82 | 83 | } else { 84 | System.out.printf("%s [%s] [%s] [%s] %s%n%s%n", 85 | tsFormat.format(timestamp), 86 | level.toString(), 87 | threadName, 88 | loggerName, 89 | message, 90 | throwable.toString()); 91 | } 92 | } 93 | 94 | /** 95 | * Decode logs 96 | * 97 | * @param processor user-provided processor called for each log message 98 | * @param waitForIt whether to wait for more data or stop after EOF reached 99 | */ 100 | public void processLogs(@NotNull ChronicleLogProcessor processor, boolean waitForIt) { 101 | ExcerptTailer tailer = cq.createTailer(); 102 | for (; ; ) { 103 | try (DocumentContext dc = tailer.readingDocument()) { 104 | Wire wire = dc.wire(); 105 | if (wire == null) 106 | if (waitForIt) { 107 | try { 108 | Thread.sleep(50L); 109 | } catch (InterruptedException ignored) { 110 | 111 | } 112 | continue; 113 | } else { 114 | break; 115 | } 116 | 117 | long timestamp = wire.read("ts").int64(); 118 | ChronicleLogLevel level = wire.read("level").asEnum(ChronicleLogLevel.class); 119 | String threadName = wire.read("threadName").text(); 120 | String loggerName = wire.read("loggerName").text(); 121 | String message = wire.read("message").text(); 122 | Throwable th = wire.hasMore() ? wire.read("throwable").throwable(false) : null; 123 | List argsL = new ArrayList<>(); 124 | if (wire.hasMore()) { 125 | wire.read("args").sequence(argsL, (l, vi) -> { 126 | while (vi.hasNextSequenceItem()) { 127 | l.add(vi.object(Object.class)); 128 | } 129 | }); 130 | } 131 | Object[] args = argsL.toArray(new Object[argsL.size()]); 132 | processor.process(timestamp, level, threadName, loggerName, message, th, args); 133 | } 134 | } 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /logger-tools/src/main/java/net/openhft/chronicle/logger/tools/internal/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This package and any and all sub-packages contains strictly internal classes for this Chronicle library. 3 | * Internal classes shall never be used directly. 4 | * 5 | * Specifically, the following actions (including, but not limited to) are not allowed 6 | * on internal classes and packages: 7 | * 8 | * Casting to 9 | * Reflection of any kind 10 | * Explicit Serialize/deserialize 11 | * 12 | * 13 | * The classes in this package and any sub-package are subject to 14 | * changes at any time for any reason. 15 | */ 16 | package net.openhft.chronicle.logger.tools.internal; 17 | -------------------------------------------------------------------------------- /logger-tools/src/test/java/net/openhft/chronicle/logger/tools/ChronicleLogReaderTest.java: -------------------------------------------------------------------------------- 1 | package net.openhft.chronicle.logger.tools; 2 | 3 | import net.openhft.chronicle.core.OS; 4 | import net.openhft.chronicle.core.util.Time; 5 | import net.openhft.chronicle.wire.WireType; 6 | import org.junit.Before; 7 | import org.junit.Test; 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | 11 | public class ChronicleLogReaderTest { 12 | @Before 13 | public void setup() { 14 | System.setProperty( 15 | "logback.configurationFile", 16 | System.getProperty("resources.path") 17 | + "/logback-chronicle-binary-appender.xml"); 18 | } 19 | 20 | @Test 21 | public void readTest() { 22 | final Logger logger = LoggerFactory.getLogger("binary-chronicle"); 23 | logger.info("test {} {} {}", 1, 100L, 100.123D); 24 | logger.info("test {} {} {}", 2, 100L, 100.123D); 25 | logger.info("test {} {} {}", 3, 100L, 100.123D); 26 | 27 | ChronicleLogReader reader = new ChronicleLogReader(OS.getTarget() + "/chronicle-logback/binary-chronicle" + Time.uniqueId(), WireType.BINARY_LIGHT); 28 | reader.processLogs(ChronicleLogReader::printf, false); 29 | 30 | //ChroniCat.main(new String[] {OS.getTarget() + "/chronicle-logback/binary-chronicle"}); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /logger-tools/src/test/resources/logback-chronicle-binary-appender.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 22 | 23 | 25 | 26 | %d %contextName [%t] %level %logger{36} - %msg%n 27 | 28 | 29 | 31 | ${java.io.tmpdir}/chronicle-logback/binary-chronicle 32 | false 33 | false 34 | 35 | 128 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 4.0.0 22 | 23 | 24 | net.openhft 25 | java-parent-pom 26 | 1.27ea1 27 | 28 | 29 | 30 | chronicle-logger 31 | 4.27ea2-SNAPSHOT 32 | pom 33 | 34 | OpenHFT/Chronicle-Logger 35 | OpenHFT :: High Performance Logging 36 | 37 | 38 | 39 | 40 | net.openhft 41 | third-party-bom 42 | 3.27ea2 43 | pom 44 | import 45 | 46 | 47 | 48 | net.openhft 49 | chronicle-bom 50 | 2.27ea-SNAPSHOT 51 | pom 52 | import 53 | 54 | 55 | 56 | 57 | net.openhft 58 | chronicle-logger-core 59 | ${project.version} 60 | 61 | 62 | 63 | net.openhft 64 | chronicle-logger-logback 65 | ${project.version} 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | net.openhft 75 | chronicle-core 76 | 77 | 78 | 79 | net.openhft 80 | chronicle-bytes 81 | 82 | 83 | 84 | net.openhft 85 | chronicle-queue 86 | 87 | 88 | 89 | org.jetbrains 90 | annotations 91 | 92 | 93 | 94 | 95 | org.apache.commons 96 | commons-lang3 97 | test 98 | 99 | 100 | junit 101 | junit 102 | test 103 | 104 | 105 | 106 | 107 | org.openjdk.jmh 108 | jmh-core 109 | test 110 | 111 | 112 | org.openjdk.jmh 113 | jmh-core-benchmarks 114 | test 115 | 116 | 117 | 118 | 119 | logger-core 120 | logger-jul 121 | logger-jcl 122 | logger-slf4j 123 | logger-slf4j-2 124 | logger-logback 125 | logger-log4j-1 126 | logger-log4j-2 127 | logger-tools 128 | benchmark 129 | 130 | 131 | 132 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 133 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 134 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 135 | master 136 | 137 | 138 | 139 | 140 | --------------------------------------------------------------------------------
13 | * The classes in this package and any sub-package are subject to 14 | * changes at any time for any reason. 15 | */ 16 | package net.openhft.chronicle.logger.tools.internal; 17 | -------------------------------------------------------------------------------- /logger-tools/src/test/java/net/openhft/chronicle/logger/tools/ChronicleLogReaderTest.java: -------------------------------------------------------------------------------- 1 | package net.openhft.chronicle.logger.tools; 2 | 3 | import net.openhft.chronicle.core.OS; 4 | import net.openhft.chronicle.core.util.Time; 5 | import net.openhft.chronicle.wire.WireType; 6 | import org.junit.Before; 7 | import org.junit.Test; 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | 11 | public class ChronicleLogReaderTest { 12 | @Before 13 | public void setup() { 14 | System.setProperty( 15 | "logback.configurationFile", 16 | System.getProperty("resources.path") 17 | + "/logback-chronicle-binary-appender.xml"); 18 | } 19 | 20 | @Test 21 | public void readTest() { 22 | final Logger logger = LoggerFactory.getLogger("binary-chronicle"); 23 | logger.info("test {} {} {}", 1, 100L, 100.123D); 24 | logger.info("test {} {} {}", 2, 100L, 100.123D); 25 | logger.info("test {} {} {}", 3, 100L, 100.123D); 26 | 27 | ChronicleLogReader reader = new ChronicleLogReader(OS.getTarget() + "/chronicle-logback/binary-chronicle" + Time.uniqueId(), WireType.BINARY_LIGHT); 28 | reader.processLogs(ChronicleLogReader::printf, false); 29 | 30 | //ChroniCat.main(new String[] {OS.getTarget() + "/chronicle-logback/binary-chronicle"}); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /logger-tools/src/test/resources/logback-chronicle-binary-appender.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 22 | 23 | 25 | 26 | %d %contextName [%t] %level %logger{36} - %msg%n 27 | 28 | 29 | 31 | ${java.io.tmpdir}/chronicle-logback/binary-chronicle 32 | false 33 | false 34 | 35 | 128 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 4.0.0 22 | 23 | 24 | net.openhft 25 | java-parent-pom 26 | 1.27ea1 27 | 28 | 29 | 30 | chronicle-logger 31 | 4.27ea2-SNAPSHOT 32 | pom 33 | 34 | OpenHFT/Chronicle-Logger 35 | OpenHFT :: High Performance Logging 36 | 37 | 38 | 39 | 40 | net.openhft 41 | third-party-bom 42 | 3.27ea2 43 | pom 44 | import 45 | 46 | 47 | 48 | net.openhft 49 | chronicle-bom 50 | 2.27ea-SNAPSHOT 51 | pom 52 | import 53 | 54 | 55 | 56 | 57 | net.openhft 58 | chronicle-logger-core 59 | ${project.version} 60 | 61 | 62 | 63 | net.openhft 64 | chronicle-logger-logback 65 | ${project.version} 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | net.openhft 75 | chronicle-core 76 | 77 | 78 | 79 | net.openhft 80 | chronicle-bytes 81 | 82 | 83 | 84 | net.openhft 85 | chronicle-queue 86 | 87 | 88 | 89 | org.jetbrains 90 | annotations 91 | 92 | 93 | 94 | 95 | org.apache.commons 96 | commons-lang3 97 | test 98 | 99 | 100 | junit 101 | junit 102 | test 103 | 104 | 105 | 106 | 107 | org.openjdk.jmh 108 | jmh-core 109 | test 110 | 111 | 112 | org.openjdk.jmh 113 | jmh-core-benchmarks 114 | test 115 | 116 | 117 | 118 | 119 | logger-core 120 | logger-jul 121 | logger-jcl 122 | logger-slf4j 123 | logger-slf4j-2 124 | logger-logback 125 | logger-log4j-1 126 | logger-log4j-2 127 | logger-tools 128 | benchmark 129 | 130 | 131 | 132 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 133 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 134 | scm:git:git@github.com:OpenHFT/Chronicle-Logger.git 135 | master 136 | 137 | 138 | 139 | 140 | --------------------------------------------------------------------------------