Skip to content

Commit

Permalink
Add CIDER log middleware
Browse files Browse the repository at this point in the history
  • Loading branch information
r0man authored and bbatsov committed Jun 27, 2023
1 parent cff4531 commit 36bb844
Show file tree
Hide file tree
Showing 11 changed files with 962 additions and 1 deletion.
1 change: 1 addition & 0 deletions .clj-kondo/config.edn
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{:hooks {:analyze-call {cider.nrepl.middleware.out/with-out-binding
hooks.core/with-out-binding}}
:lint-as {cider.nrepl.middleware.log-test/with-each-framework clojure.core/let}
:linters {:unresolved-symbol {:exclude [(cider.nrepl/def-wrapper)
(cider.nrepl.middleware.util.instrument/definstrumenter)
(cider.nrepl.middleware.util.instrument/with-break)
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## master (unreleased)

### New features

* [#773](https://github.com/clojure-emacs/cider-nrepl/pull/773) Add middleware to capture, debug, inspect and view log events emitted by Java logging frameworks.

### Changes

* Bump `orchard` to 0.12.0.
Expand Down
6 changes: 6 additions & 0 deletions doc/modules/ROOT/pages/nrepl-api/supplied_middleware.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@
| `inspect-(start/refresh/pop/push/reset/get-path)`
| Inspect a Clojure expression.

| `wrap-log`
| 0.30.1
| No
| `cider/log-add-appender`, `cider/log-add-consumer`, `cider/log-analyze-stacktrace`, `cider/log-clear-appender`, `cider/log-exceptions`, `cider/log-format-event`, `cider/log-frameworks`, `cider/log-inspect-event`, `cider/log-levels`, `cider/log-loggers`, `cider/log-remove-appender`, `cider/log-remove-consumer`, `cider/log-search`, `cider/log-update-appender`, `cider/log-update-consumer`, `cider/log-threads`
| Capture, debug, inspect and view log events emitted by Java logging frameworks.

| `wrap-macroexpand`
| -
| Yes
Expand Down
2 changes: 2 additions & 0 deletions doc/modules/ROOT/pages/usage.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ under `:repl-options`.
cider.nrepl/wrap-format
cider.nrepl/wrap-info
cider.nrepl/wrap-inspect
cider.nrepl/wrap-log
cider.nrepl/wrap-macroexpand
cider.nrepl/wrap-ns
cider.nrepl/wrap-spec
Expand Down Expand Up @@ -153,6 +154,7 @@ That's how CIDER's nREPL handler is created:
cider.nrepl/wrap-format
cider.nrepl/wrap-info
cider.nrepl/wrap-inspect
cider.nrepl/wrap-log
cider.nrepl/wrap-macroexpand
cider.nrepl/wrap-ns
cider.nrepl/wrap-out
Expand Down
7 changes: 6 additions & 1 deletion project.clj
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
^:inline-dep [cljfmt "0.9.2" :exclusions [org.clojure/clojurescript]]
^:inline-dep [org.clojure/tools.namespace "1.3.0"]
^:inline-dep [org.clojure/tools.trace "0.7.11"]
^:inline-dep [org.clojure/tools.reader "1.3.6"]]
^:inline-dep [org.clojure/tools.reader "1.3.6"]
[mx.cider/logjam "0.1.1"]]
:exclusions [org.clojure/clojure] ; see Clojure version matrix in profiles below

:pedantic? ~(if (System/getenv "CI")
Expand Down Expand Up @@ -102,9 +103,13 @@
:test {:global-vars {*assert* true}
:source-paths ["test/src"]
:java-source-paths ["test/java"]
:jvm-opts ["-Djava.util.logging.config.file=test/resources/logging.properties"]
:resource-paths ["test/resources"]
:dependencies [[boot/base "2.8.3"]
[boot/core "2.8.3"]
;; 1.3.7 and 1.4.7 are working, but we need 1.3.7 for JDK8
[ch.qos.logback/logback-classic "1.3.7"]
[org.clojure/test.check "1.1.1"]
[org.apache.httpcomponents/httpclient "4.5.13" :exclusions [commons-logging]]
[leiningen-core "2.9.10" :exclusions [org.clojure/clojure
commons-codec
Expand Down
130 changes: 130 additions & 0 deletions src/cider/nrepl.clj
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,136 @@ Depending on the type of the return value of the evaluation this middleware may
"var-name" "The var name"}
:returns {"status" "\"done\""}}}}))

(def-wrapper wrap-log cider.nrepl.middleware.log/handle-log
{:doc "Middleware that captures log events and makes them inspect-able."
:requires #{#'session #'wrap-print}
:handles
{"cider/log-add-appender"
{:doc "Add an appender to a log framework."
:requires {"framework" "The id of the log framework."
"appender" "The name of the appender."
"filters" "A map from filter name to filter condition."
"size" "The number of events the appender keeps in memory."
"threshold" "The threshold in percent used to cleanup events."}
:optional {"logger" "The name of the logger to attach to."}
:returns {"status" "done"
"cider/log-add-appender" "The appender that was added."}}

"cider/log-add-consumer"
{:doc "Add a consumer to an appender of a log framework."
:requires {"framework" "The id of the log framework."
"appender" "The name of the appender."
"filters" "A map from filter name to filter condition."}
:returns {"status" "done"
"cider/log-add-consumer" "The consumer that was added."}}

"cider/log-analyze-stacktrace"
{:doc "Analyze the stacktrace of a log event."
:requires {"framework" "The id of the log framework."
"appender" "The name of the appender."
"event" "The id of the event to inspect."}
:returns {"status" "done"}}

"cider/log-clear-appender"
{:doc "Clear all events of a log appender."
:requires {"framework" "The id of the log framework."
"appender" "The name of the appender."}
:returns {"status" "done"
"cider/log-clear-appender" "The appender that was cleared."}}

"cider/log-exceptions"
{:doc "Return the exceptions and their frequencies for the given framework and appender."
:requires {"framework" "The id of the log framework."
"appender" "The name of the appender."}
:returns {"status" "done"
"cider/log-exceptions" "A map from exception name to event frequency."}}

"cider/log-frameworks"
{:doc "Return the available log frameworks."
:returns {"status" "done"
"cider/log-frameworks" "A list of log frameworks."}}

"cider/log-format-event"
{:doc "Format a log event."
:requires {"framework" "The id of the log framework."
"appender" "The name of the log appender."
"event" "The id of the log event."}
:optional wrap-print-optional-arguments
:returns {"status" "done"
"cider/log-format-event" "The formatted log event."}}

"cider/log-inspect-event"
{:doc "Inspect a log event."
:requires {"framework" "The id of the log framework."
"appender" "The name of the appender."
"event" "The id of the event to inspect."}
:returns {"status" "done"
"value" "The inspection result."}}

"cider/log-levels"
{:doc "Return the log levels and their frequencies for the given framework and appender."
:requires {"framework" "The id of the log framework."
"appender" "The name of the appender."}
:returns {"status" "done"
"cider/log-levels" "A map from log level to event frequency."}}

"cider/log-loggers"
{:doc "Return the loggers and their frequencies for the given framework and appender."
:requires {"framework" "The id of the log framework."
"appender" "The name of the appender."}
:returns {"status" "done"
"cider/log-loggers" "A map from logger name to event frequency."}}

"cider/log-remove-appender"
{:doc "Remove an appender from a log framework."
:requires {"framework" "The id of the log framework."
"appender" "The name of the appender."}
:returns {"status" "done"
"cider/log-remove-appender" "The removed appender."}}

"cider/log-remove-consumer"
{:doc "Remove a consumer from the appender of a log framework."
:requires {"framework" "The id of the log framework."
"appender" "The name of the appender."
"consumer" "The name of the consumer."}
:returns {"status" "done"
"cider/log-add-consumer" "The removed consumer."}}

"cider/log-update-appender"
{:doc "Update the appender of a log framework."
:requires {"framework" "The id of the log framework."
"appender" "The name of the appender."
"filters" "A map from filter name to filter condition."
"size" "The number of events the appender keeps in memory."
"threshold" "The threshold in percent used to cleanup events."}
:returns {"status" "done"
"cider/log-update-appender" "The updated appender."}}

"cider/log-update-consumer"
{:doc "Update the consumer of a log appender."
:requires {"framework" "The id of the log framework."
"appender" "The name of the appender."
"consumer" "The name of the consumer."
"filters" "A map from filter name to filter condition."}
:returns {"status" "done"
"cider/log-update-consumer" "The consumer that was updated."}}

"cider/log-search"
{:doc "Search the log events of an appender."
:requires {"framework" "The id of the log framework."
"appender" "The name of the appender."}
:optional {"filters" "A map from filter name to filter condition."
"limit" "Number of log events to return."}
:returns {"status" "done"
"cider/log-search" "The list of log events matching the search."}}

"cider/log-threads"
{:doc "Return the threads and their frequencies for the given framework and appender."
:requires {"framework" "The id of the log framework."
"appender" "The name of the appender."}
:returns {"status" "done"
"cider/log-threads" "A map from thread name to event frequency."}}}})

(def-wrapper wrap-macroexpand cider.nrepl.middleware.macroexpand/handle-macroexpand
(cljs/requires-piggieback
{:doc "Macroexpansion middleware."
Expand Down
1 change: 1 addition & 0 deletions src/cider/nrepl/middleware.clj
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
cider.nrepl/wrap-format
cider.nrepl/wrap-info
cider.nrepl/wrap-inspect
cider.nrepl/wrap-log
cider.nrepl/wrap-macroexpand
cider.nrepl/wrap-ns
cider.nrepl/wrap-out
Expand Down
Loading

0 comments on commit 36bb844

Please sign in to comment.