Logging
CIDER Log Mode allows you to capture, debug, inspect and view log events emitted by Java logging frameworks. The captured log events can be searched, streamed to the client, pretty-printed, and are integrated with the CIDER Inspector and Stacktrace Mode. Here is a screenshot of CIDER Log Mode in action.
The screenshot displays the list of log events in the
*cider-log* buffer on the left. To the right, a log event is
visible in the *cider-inspect* buffer, where the exception of the
event is also displayed in the CIDER Stacktrace Mode. From the
Stacktrace Mode buffer you can jump to the source of each frame. At
the bottom the CIDER log menu is shown from which you can perform
logging related actions.
|
Features
-
Browse Javadocs and website of the given log framework.
-
Search log events and show them in buffers.
-
Pretty-print log events.
-
Show log events in the CIDER Inspector.
-
Show log event exceptions in the CIDER Stacktrace Mode.
-
Integration with logview.
Dependencies
Logview is an optional dependency
of CIDER Log Mode. We recommend using it, since it is responsible for
coloring the log events and it provides other useful features, such as
syntax highlighting, filtering and more. It is used automatically when
available, and its use can be customized via cider-log-use-logview
.
transient-mode
It’s worth pointing out that most features and workflows of Cider Log Mode are based on transient-mode.
A transient menu is the following widget:
Its usage is mostly self-describing, since each command has its keybinding attached to the description.
Getting started
To use CIDER Log Mode, there two main ways to get started:
-
M-x cider-log-event
, which uses transient-mode and will not immediately show the logs (you should use transient-mode to show the*cider-log*
buffer) -
M-x cider-log-show
is a newer function that intends to be an "all-in-one" command, intended for a streamlined experience, which can be useful to get started, or for casual usage.-
It doesn’t use transient-mode - it aims to do everything in one step
-
It immediately shows the
*cider-log*
buffer
-
Any of these commands will only succeed in a buffer that has a CIDER repl (Sesman session) attached to it. |
Via cider-log-show
By using M-x cider-log-show
, all setup and rendering will be performed for you in a single step that doesn’t pop up a transient-mode
menu:
-
A framework will be set up, automatically
-
You may be prompted for a framework
-
You can prevent the prompt by customizing
cider-log-framework-name
(best done indir-locals.el
)
-
-
A log appender and a log consumer will be setup, automatically
-
The
*cider-log*
buffer will be rendered.
All these steps are idempotent, so it’s safe to run M-x cider-log-show
more than once.
You can refine the setup afterwards (e.g. configuring filtering) by running M-x cider-log
, M-x cider-log-consumer
, etc.
Via cider-log-event
The intended workflow for this function is as follows:
-
Run
M-x cider-log-event
-
A framework will be set up, automatically
-
You may be prompted for a framework
-
You can prevent the prompt by customizing
cider-log-framework-name
(best done indir-locals.el
)
-
-
A log appender and a log consumer will be setup, automatically
-
The
*cider-log*
buffer will not be rendered-
For it to be rendered, press
s
(Search log events
) within the transient-mode menu.
-
The *cider-log* buffer might initially be empty, and you may
see a No log events found message. This is because nothing has been
logged between adding the appender and searching for events. So, now
would be a good time to run some code that triggers a log event for
the selected framework.
|
Advanced usage
cider-log
is a function that can serve both to set up logging from scratch,
or for tweaking an existing setup (e.g. add filtering to a consumer).
It’s considered a lower-level approach.
Setup via cider-log
Type C-c M-l l or M-x cider-log. The first time you run the command, it will
prompt you to select a log framework to use, and then attach a log
appender to the root logger of the selected framework. After the log
appender has been attached, the cider-log
command will show a
Transient
menu, from which you can take further actions, like managing the log
framework, appenders, consumers and events.
You should add a log appender and a log consumer at this point - else no log entries will be possibly shown
(which is why cider-log
is considered a lower-level workflow).
After that, to view log events and stream them to your client, type es
(Search log events) followed by s. This will open the
*cider-log*
buffer showing any log events captured thus far. It will
also add a log consumer to this buffer, which receives newly-arriving
log events.
Keybindings
Command |
Keyboard shortcut |
Description |
|
C-c M-l e |
Show the menu to manage log events via a transient-mode menu. This is one of the two main entrypoints to get started. |
|
C-c M-l s |
Immediately shows the logs, without a transient-mode menu. This is one of the two main entrypoints to get started. |
|
C-c M-l l |
Show the CIDER log menu. Please note that this is considered advanced usage. |
|
C-c M-l f |
Show the menu to manage a logging framework. |
|
C-c M-l a |
Show the menu to manage appenders of a logging framework. |
|
C-c M-l c |
Show the menu to manage consumers listening to log events. |
Log framework
CIDER Log Mode supports log frameworks that allow reconfiguration at runtime. More specifically the framework should support attaching log appenders to loggers, in order to capture events.
At the moment the following log frameworks are supported:
if you choose Timbre, please make sure that your project’s version roughly matches Logjam's expected version - otherwise incompatible changes may make Timbre not appear available as a CIDER Log Mode framework option. |
There is some work in progress to support Log4j as well, but there are some difficulties with configuration changes made at runtime, which are wiped out by the Log4j2 reconfiguration mechanism.
If your logging framework of choice is not currently supported by CIDER Log Mode,
you can opt to use Clojure’s official tools.logging façade in your project, such that you can locally,
unobstrusively tell it to use a supported framework (like Logback) instead of your project’s default one.
Note that its choice of logging backend implementation can be controlled with the
-Dclojure.tools.logging.factory Java system property, which can be cleanly customized locally via Lein profiles,
or Clojure CLI aliases.
|
Keybindings
Command | Keyboard shortcut | Description |
---|---|---|
|
C-c M-l f s |
Select the log framework to use. |
|
C-c M-l f b |
Select the log buffer to user. Default: |
|
C-c M-l f j |
Browse the Javadocs of the log framework. |
|
C-c M-l f w |
Browse the website of the log framework. |
Log Appender
In order to capture log events, a log appender needs to be attached to a logger of a framework. Once an appender is attached to a logger it captures the log events emitted by the framework in an in-memory atom. A log appender can be configured to have a certain size (default: 100000) and a threshold in percentage (default: 10). Log events are cleared from the appender when threshold (appender size plus threshold) is reached. Additionally an appender can be configured to only capture events that match a set of filters.
Keybindings
The following keybindings can be used to interact with log appenders.
Command | Keyboard shortcut | Description |
---|---|---|
|
C-c M-l a |
Show the transient menu to manage log appenders. |
|
C-c M-l a a |
Add a log appender to a logger. |
|
C-c M-l a c |
Clear all captured events of a log appender. |
|
C-c M-l a k |
Kill a log appender by removing it from the logger. |
|
C-c M-l a u |
Update the filters, size or threshold of a log appender. |
Log Consumer
Log events can be streamed to a client by attaching a log consumer to an appender. Once a log consumer has been attached to an appender, it will receive events from the appender. Similar to log appenders, consumers can also be configured with a set of filters to only receive certain events.
Keybindings
The following keybindings can be used to interact with log consumers.
Command | Main / Consumer Menu | Keyboard shortcut | Description |
---|---|---|---|
|
C-c M-l c |
Show the transient menu to manage log consumers. |
|
|
ca / a |
C-c M-l c a |
Add a log consumer to a log appender streaming event to the client. |
|
ck / k |
C-c M-l c k |
Kill a log consumer and stop streaming events to the client. |
|
cu / u |
C-c M-l c u |
Update the filters of a log consumer to change which events are streamed to the client. |
Log Event
Log events can be searched, streamed to a client or viewed in CIDER’s
Inspector and Stacktrace Mode. When searching log events the user can
specify a set of filters. Events that match the filters are shown in
the *cider-log*
buffer. Additionally a log consumer will be
attached to the appender to receive log events matching the search
criteria after the search command has been issued. The log appender
will be removed automatically once a new search has been submitted or
when the *cider-log*
buffer gets killed.
Keybindings
The following keybindings can be used to interact with log events.
Command | Keyboard shortcut | Description |
---|---|---|
|
C-c M-l e |
Show the transient menu to manage log events. |
|
C-c M-l e c |
Clear all events from the log event buffer. |
|
C-c M-l e e |
Show the stacktrace of the log event at point in the CIDER Stacktrace Mode. |
|
C-c M-l e i |
Show the log event in the CIDER Inspector. |
|
C-c M-l e p |
Pretty print the log event in the |
|
C-c M-l e s |
Search log events and show them in the |
Log Filters
Filters for log events can be attached to log appenders and consumers. They also take effect when searching events or streaming them to clients. If multiple filters are chosen they are combined using logical AND condition. The following filters are available:
Filter | Keyboard shortcut | Description |
---|---|---|
|
-e |
Only include log events that were emitted before |
|
-E |
Only include log events caused by an exception in the list of |
|
-l |
Only include log events with a log level above |
|
-L |
Only include log events that were emitted by a logger in the list of |
|
-r |
Only include log events whose message matcches the regular expression |
|
-s |
Only include log events that were emitted at, or after |
|
-t |
Only include log events that were emitted by a thread in the list of |