|
1 | 1 | # Logging |
2 | 2 |
|
3 | | -Logging macros which delegate to a specific logging implementation. At runtime a specific implementation is selected from, in order, slf4j, Apache commons-logging, log4j2, log4j, and finally java.util.logging. |
| 3 | +Logging macros which delegate to a specific logging implementation, selected |
| 4 | +at runtime when the `clojure.tools.logging` namespace is first loaded. |
4 | 5 |
|
5 | | -Logging levels are specified by clojure keywords, in increasingly severe order: |
| 6 | +## Installation |
| 7 | + |
| 8 | +Lastest stable release is [0.5.0] |
| 9 | + |
| 10 | +Leiningen: |
6 | 11 |
|
7 | 12 | ```clojure |
8 | | -:trace, :debug, :info, :warn, :error, :fatal |
| 13 | +[org.clojure/tools.logging "0.5.0"] |
| 14 | +``` |
| 15 | + |
| 16 | +Maven: |
| 17 | + |
| 18 | +```xml |
| 19 | +<dependency> |
| 20 | + <groupId>org.clojure</groupId> |
| 21 | + <artifactId>tools.logging</artifactId> |
| 22 | + <version>0.5.0</version> |
| 23 | +</dependency> |
9 | 24 | ``` |
10 | 25 |
|
11 | | -Logging occurs with the `log` macro, or the level-specific convenience macros (e.g., `debug`, `debugf`). Only when the specified logging level is enabled will the message arguments be evaluated and the underlying logging implementation be invoked. By default that invocation will occur via an agent when inside a running STM transaction. |
| 26 | +Gradle: |
12 | 27 |
|
13 | | -Unless otherwise specified, the current namespace (as identified by `*ns*`) will be used as the log-ns (similar to how the java class name is usually used). Note: you should configure your logging implementation to display the name that was passed to it; if it instead performs stack-inspection you'll see some ugly and unhelpful text in your logs. |
| 28 | +```clojure |
| 29 | +compile "org.clojure:tools.logging:0.5.0" |
| 30 | +``` |
14 | 31 |
|
15 | | -You can redirect all java writes of `System.out` and `System.err` to the log system by calling `log-capture!`. To bind `*out*` and `*err*` to the log system invoke `with-logs`. In both cases a log-ns value must be specified in order to namespace the output. |
16 | 32 |
|
17 | 33 | ## Usage |
18 | 34 |
|
19 | | -The latest API documentation can be found at http://clojure.github.com/tools.logging |
| 35 | +[Latest API Documentation](http://clojure.github.com/tools.logging) |
20 | 36 |
|
21 | | -The following short example should give you what you need to get started: |
| 37 | +Logging occurs with the `log` macro, or the level-specific convenience macros |
| 38 | +(e.g., `debug`, `debugf`). Only when the specified logging level is enabled will |
| 39 | +the message arguments be evaluated and the underlying logging implementation be |
| 40 | +invoked. By default that invocation will occur via an agent when inside a running |
| 41 | +STM transaction. |
22 | 42 |
|
23 | | -```clojure |
24 | | -(ns example.math |
25 | | - (:require [clojure.tools.logging :as log])) |
26 | | - |
27 | | -(defn divide [x y] |
28 | | - (log/info "dividing" x "by" y) |
29 | | - (try |
30 | | - (log/spyf "result is %s" (/ x y)) ; yields the result |
31 | | - (catch Exception ex |
32 | | - (log/error ex "There was an error in calculation")))) |
33 | | -``` |
| 43 | +### Namespacing of log entries |
34 | 44 |
|
35 | | -Example repl output using the configuration below: |
| 45 | +Unless otherwise specified, the current namespace (as identified by `*ns*`) will |
| 46 | +be used as the log-ns. This value can be emitted in the log entry, and used by most |
| 47 | +logging implementations when using namespace-specific logging levels. |
36 | 48 |
|
37 | | -``` |
38 | | -user=> (use 'my.example) |
39 | | -nil |
40 | | -user=> (divide 1 2) |
41 | | -INFO example.math: dividing 1 by 2 |
42 | | -DEBUG example.math: result is 1/2 |
43 | | -1/2 |
44 | | -user=> (divide 2 0) |
45 | | -INFO example.math: dividing 2 by 0 |
46 | | -ERROR example.math: There was an error in calculation |
47 | | -java.lang.ArithmeticException: Divide by zero |
48 | | - at clojure.lang.Numbers.divide(Numbers.java:156) |
49 | | - ... |
50 | | -``` |
| 49 | +Note: You should configure your logging implementation to display the name that |
| 50 | +was passed to it. If it instead performs stack-inspection you'll see some ugly |
| 51 | +and unhelpful text in your logs. |
51 | 52 |
|
52 | | -For those new to using a java logging library, the following is a very basic configuration for log4j. Place it in a file called `log4j.properties` and place that file (and the log4j JAR) on the classpath. |
| 53 | +### Redirecting output to logs |
53 | 54 |
|
54 | | -``` |
55 | | -log4j.rootLogger=INFO, console |
56 | | -log4j.logger.example=DEBUG |
57 | | -log4j.appender.console=org.apache.log4j.ConsoleAppender |
58 | | -log4j.appender.console.layout=org.apache.log4j.PatternLayout |
59 | | -log4j.appender.console.layout.ConversionPattern=%-5p %c: %m%n |
60 | | -``` |
| 55 | +You can redirect all java writes of `System.out` and `System.err` to the log |
| 56 | +system by calling `log-capture!`. To bind `*out*` and `*err*` to the log system |
| 57 | +invoke `with-logs`. In both cases a log-ns value must be specified in order to |
| 58 | +namespace the output. |
61 | 59 |
|
62 | | -The above will print messages to the console for `:debug` or higher if one is in the `example` namespace, and `:info` or higher in all other namespaces. |
| 60 | +## Configuration |
63 | 61 |
|
64 | | -### Installation |
| 62 | +_NOTE: Logging configuration (e.g., setting of logging levels, formatting) is |
| 63 | +specific to the underlying logging implementation, and is out of scope for this |
| 64 | +library._ |
65 | 65 |
|
66 | | -Logging is available in Maven central. Add it to your Maven project's `pom.xml`: |
| 66 | +### Selecting a logging implementation |
67 | 67 |
|
68 | | -```xml |
69 | | -<dependency> |
70 | | - <groupId>org.clojure</groupId> |
71 | | - <artifactId>tools.logging</artifactId> |
72 | | - <version>0.5.0</version> |
73 | | -</dependency> |
74 | | -``` |
| 68 | +To control which logging implementation is used, set the `clojure.tools.logging.factory` |
| 69 | +system property to the fully-qualified name of a no-arg function that returns an |
| 70 | +instance of `clojure.tools.logging.impl/LoggerFactory`. There are a number of |
| 71 | +factory functions provided in the `clojure.tools.logging.impl` namespace. |
75 | 72 |
|
76 | | -or your leiningen project.clj: |
| 73 | +[Leiningen example]: |
77 | 74 |
|
78 | 75 | ```clojure |
79 | | -[org.clojure/tools.logging "0.5.0"] |
| 76 | +:jvm-opts ["-Dclojure.tools.logging.factory=clojure.tools.logging.impl/slf4j-factory"] |
80 | 77 | ``` |
81 | 78 |
|
82 | | -Please note the changelog below. |
| 79 | +If the system property is unset, an implementation will be automatically chosen |
| 80 | +based on whichever of the following implementations is successfully loaded first: |
83 | 81 |
|
84 | | -### Building Logging |
| 82 | +1. [SLF4J] |
| 83 | +2. [Apache Commons Logging] |
| 84 | +3. [Log4J 2] |
| 85 | +4. [Log4J] |
| 86 | +5. [java.util.logging] |
| 87 | + |
| 88 | +The above approach is problematic given that applications often inadvertently pull |
| 89 | +in multiple logging implementations as transitive dependencies. As such, it is |
| 90 | +_strongly_ advised that you set the system property. |
85 | 91 |
|
86 | | -0. Clone the repo |
87 | | -1. Make sure you have maven installed |
88 | | -2. Run the maven build; run either: |
89 | | - 1. `mvn install`: This will produce a logging jar file in the `target` |
90 | | -directory, and run all tests with the most recently-released build |
91 | | -of Clojure. |
92 | 92 |
|
93 | 93 | ## Thanks |
94 | 94 |
|
95 | 95 | * Chris Dean |
96 | 96 | * Phil Hagelberg |
97 | 97 | * Richard Newman |
| 98 | +* Sean Corfield |
98 | 99 | * Timothy Pratley |
99 | 100 |
|
100 | 101 | ## License |
101 | 102 |
|
102 | 103 | Copyright © 2009 Alex Taggart |
103 | 104 |
|
104 | 105 | Licensed under the EPL. (See the file epl.html.) |
| 106 | + |
| 107 | + |
| 108 | +[0.5.0]: https://github.com/clojure/tools.logging/tree/tools.logging-0.5.0 |
| 109 | +[Leiningen example]: https://github.com/technomancy/leiningen/blob/master/doc/TUTORIAL.md#setting-jvm-options |
| 110 | +[SLF4J]: http://www.slf4j.org/ |
| 111 | +[Apache Commons Logging]: https://commons.apache.org/logging |
| 112 | +[Log4J 2]: https://logging.apache.org/log4j/2.x/ |
| 113 | +[Log4J]: http://logging.apache.org/log4j/1.2/ |
| 114 | +[java.util.logging]: https://docs.oracle.com/en/java/javase/13/docs/api/java.logging/java/util/logging/package-summary.html |
0 commit comments