Uncial is a fast and easy to use logging system. The goal is to be fast and easy not "full featured."
-
It's fast! See Speed below.
-
It's lean! The code base consists of 1 dependenciy, 22 files and < 2400 lines of commented/javadoc/formatted code.
-
Supports dynamic configuration via JMX.
-
Natively implements SLF4J.
-
Uncial supports
printf
style format strings. Like SLF4J's parameterized logging (see here for an explanation), this gives Uncial a performance boost without the user needing to write ugly "if enabled" code blocks. Unlike, SLF4J, however, Uncial uses the standardprintf
format style in conjunction with varargs. This style is familiar to developers and using varargs allows for easier usage when logging many arguments.
This is basically the same pattern as LOG4J or SLF4J.
private static final Logger LOG = Loggers.get(MyClass.class);
LOG.trace("Your os is '%s' and you have %d CPUs.", System.getProperty("os.name"), Runtime.getRuntime().availableProcessors());
Same methods as the Logger
interface but accessed statically. Note, this does not sacrifice knowing the Class
from which the log call originated (albeit it does incur a performance penalty, ~90% from ~2.5 us to ~4.7 us per log call).
Log.trace("Your os is '%s' and you have %d CPUs.", System.getProperty("os.name"), Runtime.getRuntime().availableProcessors());
No xml configuration. Configuration is done in java code or via JMX. By default, no Appenders
are configured. So at a minimum you'll need to configure an Appender
. Don't worry it's easy!
Here are some examples:
UncialConfig config = UncialConfig.get();
config.addAppender(new ConsoleAppender());
config.addAppender(new FileAppender("/tmp/myapplication.log"));
config.addAppender(new RollingFileAppender("/tmp/myapplication.log", 1, TimeUnit.DAYS));
config.addAppender(new RollingFileAppender("/tmp/myapplication.log", 5, SizeUnit.MEGABYTES));
config.addAppender(new ConsoleAppender());
config.addAppender(new FileAppender("/tmp/myapplication.log"));
config.setLevel("org.apache", Logger.warn); // any class with package starting with 'org.apache'
config.setLevel(StringUtils.class, Logger.error);
As one would expect, all the above configurations can be mixed and matched.
Take a look at net.ocheyedan.uncial.UncialConfig
for a complete list of configuration options and defaults (it is also the MBean
for JMX).
The benchmarking tests are done with caliper and the source for all tests can be found in the test directory.
In general Uncial is about 2x faster than Logback and 14x faster than Log4j. The full caliper results are hosted here but here's some explanation of some of the results.
This test uses a log thread with printf-style formatting (default uncial configuration) for Uncial. Logback and Log4j are not (cannot) using a log thread. Benchmark was run using the equivalent FileAppender for each implementation and using the equivalent appender format of %d{MM/dd/yyyy HH:mm:ss.SSS} %C [%c] - %m%n
Benchmark | Logger | Time (us) | Linear Runtime | % |
---|---|---|---|---|
Message (0 params) | ||||
Uncial | 2.74 | = | 100% | |
Logback | 5.57 | === | 203% | |
Log4j | 44.13 | ============================= | 1,612% | |
Message (1 params) | ||||
Uncial | 3.14 | == | 115% | |
Logback | 6.32 | ==== | 231% | |
Log4j | 44.46 | ============================= | 1,625% | |
Message (many params) | ||||
Uncial | 6.40 | ==== | 234% | |
Logback | 7.01 | ==== | 256% | |
Log4j | 44.52 | ============================== | 1,627% |
See here for full results of this test with more trials.
This test does not use a log thread and has printf-style formatting for Uncial. Benchmark was run using the equivalent FileAppender for each implementation and using the equivalent appender format of %d{MM/dd/yyyy HH:mm:ss.SSS} %C [%c] - %m%n
Benchmark | Logger | Time (us) | Linear Runtime | % |
---|---|---|---|---|
Message (0 params) | ||||
Uncial | 2.94 | = | 100% | |
Logback | 5.74 | === | 196% | |
Log4j | 45.45 | ============================= | 1,548% | |
Message (1 params) | ||||
Uncial | 3.25 | == | 111% | |
Logback | 6.27 | ==== | 214% | |
Log4j | 44.95 | ============================= | 1,531% | |
Message (many params) | ||||
Uncial | 6.61 | ==== | 225% | |
Logback | 7.15 | ==== | 244% | |
Log4j | 44.45 | ============================= | 1,548% |
See here for full results of this test with more trials.
This test does not use a log thread and has SLF4J-style formatting for Uncial. Benchmark was run using the equivalent FileAppender for each implementation and using the equivalent appender format of %d{MM/dd/yyyy HH:mm:ss.SSS} %C [%c] - %m%n
Benchmark | Logger | Time (us) | Linear Runtime | % |
---|---|---|---|---|
Message (0 params) | ||||
Uncial | 3.27 | == | 100% | |
Logback | 5.64 | === | 174% | |
Log4j | 45.14 | ============================= | 1,382% | |
Message (1 params) | ||||
Uncial | 3.94 | == | 121% | |
Logback | 6.52 | ==== | 200% | |
Log4j | 45.39 | ============================== | 1,390% | |
Message (many params) | ||||
Uncial | 3.22 | == | 99% | |
Logback | 7.11 | ==== | 220% | |
Log4j | 45.16 | ============================= | 1,383% |
See here for full results of this test with more trials.
This test uses a log thread and has SLF4J-style formatting for Uncial. Logback and Log4j are not (cannot) using a log thread. Benchmark was run using the equivalent FileAppender for each implementation and using the equivalent appender format of %d{MM/dd/yyyy HH:mm:ss.SSS} %C [%c] - %m%n
Benchmark | Logger | Time (us) | Linear Runtime | % |
---|---|---|---|---|
Message (0 params) | ||||
Uncial | 3.12 | == | 100% | |
Logback | 5.59 | === | 179% | |
Log4j | 45.12 | ============================ | 1,446% | |
Message (1 params) | ||||
Uncial | 3.32 | == | 107% | |
Logback | 6.43 | ==== | 206% | |
Log4j | 45.49 | ============================== | 1,458% | |
Message (many params) | ||||
Uncial | 3.24 | == | 104% | |
Logback | 7.49 | ==== | 240% | |
Log4j | 45.41 | ============================= | 1,456% |
See here for full results of this test with more trials.
The SLF4J formatting for Uncial is slower with no arguments but much better than the printf style formatter when handling many arguments (which is why it is included in Uncial). Take a look at the caliper results as they include many more tests and details worth noting.
This test uses the default Uncial configuration in terms of log-thread and formatting style however it changes the appender formatter for all implementations to utilize the expensive options of logging method name, line number and file name of the invoking log call. Benchmark was run using the equivalent FileAppender for each implementation and using the equivalent appender format of %d{MM/dd/yyyy HH:mm:ss.SSS} %t %F %C#%M @ %L [%c] - %m%n
Benchmark | Logger | Time (us) | Linear Runtime | % |
---|---|---|---|---|
Message (0 params) | ||||
Uncial | 25.4 | ============= | 100% | |
Logback | 53.6 | ============================= | 210% | |
Log4j | 44.1 | ======================== | 173% | |
Message (1 params) | ||||
Uncial | 27.8 | =============== | 109% | |
Logback | 54.1 | ============================= | 213% | |
Log4j | 45.3 | ======================== | 178% | |
Message (many params) | ||||
Uncial | 31.4 | ================= | 123% | |
Logback | 54.9 | ============================== | 216% | |
Log4j | 45.3 | ======================== | 178% |
See here for full results of this test with more trials.
Uncial natively implements the org.slf4j.Logger interface and is configured properly so that as long as you have the uncial jar in your classpath and use the SLF4J interfaces, you'll automatically be using Uncial as your logger (and get the speed benefits too!).
Using Uncial via SLF4J will limit you to using the SLF4J style (i.e., {}) parameterized logging. Uncial is planned to be augmented in the future to also support printf
style logging with SLF4J.
You obtain it the same as any other SLF4J implementation:
private static final Logger LOG = LoggerFactory.getLogger(MyClass.class);