Skip to content

Commit

Permalink
[new] Add SLF4Jv2 backend/provider
Browse files Browse the repository at this point in the history
Adapted from Telemere
  • Loading branch information
ptaoussanis committed Aug 29, 2024
1 parent b3d157a commit 2ed6b43
Show file tree
Hide file tree
Showing 9 changed files with 400 additions and 11 deletions.
5 changes: 3 additions & 2 deletions project.clj
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,10 @@
:dependencies
[[org.clojure/test.check "1.1.1"]
[org.clojure/tools.logging "1.3.0"]
[org.slf4j/slf4j-api "2.0.16"]
[com.taoensso/timbre-slf4j "6.6.0-SNAPSHOT"]
[com.taoensso/nippy "3.4.2"]
[com.taoensso/carmine "3.4.1"
:exclusions [com.taoensso/timbre]]
[com.taoensso/carmine "3.4.1" :exclusions [com.taoensso/timbre]]
[com.draines/postal "2.0.5"]]

:plugins
Expand Down
15 changes: 15 additions & 0 deletions slf4j/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
pom.xml*
.lein*
.nrepl-port
*.jar
*.class
.env
.DS_Store
/lib/
/classes/
/target/
/checkouts/
/logs/
/.clj-kondo/.cache
.idea/
*.iml
29 changes: 29 additions & 0 deletions slf4j/project.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
(defproject com.taoensso/timbre-slf4j "6.6.0-SNAPSHOT"
:author "Peter Taoussanis <https://www.taoensso.com>"
:description "Timbre backend/provider for SLF4J API v2"
:url "https://www.taoensso.com/timbre"

:license
{:name "Eclipse Public License - v 1.0"
:url "https://www.eclipse.org/legal/epl-v10.html"}

:scm {:name "git" :url "https://github.com/taoensso/timbre"}

:java-source-paths ["src/java"]
:javac-options ["--release" "8" "-g"] ; Support Java >= v8
:dependencies []

:profiles
{:provided
{:dependencies
[[org.clojure/clojure "1.11.4"]
[org.slf4j/slf4j-api "2.0.16"]
[com.taoensso/timbre "6.6.0-SNAPSHOT"]]}

:dev
{:plugins
[[lein-pprint "1.3.2"]
[lein-ancient "0.7.0"]]}}

:aliases
{"deploy-lib" ["do" #_["build-once"] ["deploy" "clojars"] ["install"]]})
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
com.taoensso.timbre.slf4j.TimbreServiceProvider
78 changes: 78 additions & 0 deletions slf4j/src/java/com/taoensso/timbre/slf4j/TimbreLogger.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/**
* Copyright (c) 2004-2011 QOS.ch
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
package com.taoensso.timbre.slf4j;
// Based on `org.slf4j.simple.SimpleLogger`

import java.io.Serializable;

import org.slf4j.Logger;
import org.slf4j.Marker;
import org.slf4j.event.Level;
import org.slf4j.event.LoggingEvent;
import org.slf4j.helpers.LegacyAbstractLogger;
import org.slf4j.spi.LoggingEventAware;

import clojure.java.api.Clojure;
import clojure.lang.IFn;

public class TimbreLogger extends LegacyAbstractLogger implements LoggingEventAware, Serializable {

private static final long serialVersionUID = -1999356203037132557L;

private static boolean INITIALIZED = false;
static void lazyInit() {
if (INITIALIZED) { return; }
INITIALIZED = true;
init();
}

private static IFn logFn;
private static IFn isAllowedFn;

static void init() {
IFn requireFn = Clojure.var("clojure.core", "require");
requireFn.invoke(Clojure.read("taoensso.timbre.slf4j"));
isAllowedFn = Clojure.var("taoensso.timbre.slf4j", "allowed?");
logFn = Clojure.var("taoensso.timbre.slf4j", "log!");
}

protected TimbreLogger(String name) { this.name = name; }

protected boolean isLevelEnabled(Level level) { return (boolean) isAllowedFn.invoke(this.name, level); }
public boolean isTraceEnabled() { return (boolean) isAllowedFn.invoke(this.name, Level.TRACE); }
public boolean isDebugEnabled() { return (boolean) isAllowedFn.invoke(this.name, Level.DEBUG); }
public boolean isInfoEnabled() { return (boolean) isAllowedFn.invoke(this.name, Level.INFO); }
public boolean isWarnEnabled() { return (boolean) isAllowedFn.invoke(this.name, Level.WARN); }
public boolean isErrorEnabled() { return (boolean) isAllowedFn.invoke(this.name, Level.ERROR); }

public void log(LoggingEvent event) { logFn.invoke(this.name, event); } // Fluent (modern) API, called after level check

@Override protected String getFullyQualifiedCallerName() { return null; }
@Override
protected void handleNormalizedLoggingCall(Level level, Marker marker, String messagePattern, Object[] arguments, Throwable throwable) {
logFn.invoke(this.name, level, throwable, messagePattern, arguments, marker); // Legacy API, called after level check
}

}
54 changes: 54 additions & 0 deletions slf4j/src/java/com/taoensso/timbre/slf4j/TimbreLoggerFactory.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/**
* Copyright (c) 2004-2011 QOS.ch
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
package com.taoensso.timbre.slf4j;
// Based on `org.slf4j.simple.SimpleLoggerFactory`

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import org.slf4j.Logger;
import org.slf4j.ILoggerFactory;

public class TimbreLoggerFactory implements ILoggerFactory {

ConcurrentMap<String, Logger> loggerMap;

public TimbreLoggerFactory() {
loggerMap = new ConcurrentHashMap<>();
TimbreLogger.lazyInit();
}

public Logger getLogger(String name) {
return loggerMap.computeIfAbsent(name, this::createLogger);
}

protected Logger createLogger(String name) {
return new TimbreLogger(name);
}

protected void reset() {
loggerMap.clear();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/**
* Copyright (c) 2004-2011 QOS.ch
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
package com.taoensso.timbre.slf4j;
// Based on `org.slf4j.simple.SimpleServiceProvider`

import org.slf4j.ILoggerFactory;
import org.slf4j.IMarkerFactory;
import org.slf4j.helpers.BasicMarkerFactory;
import org.slf4j.helpers.BasicMDCAdapter;
import org.slf4j.spi.MDCAdapter;
import org.slf4j.spi.SLF4JServiceProvider;

public class TimbreServiceProvider implements SLF4JServiceProvider {

public static String REQUESTED_API_VERSION = "2.0.99"; // Should not be final

private ILoggerFactory loggerFactory;
private IMarkerFactory markerFactory;
private MDCAdapter mdcAdapter;

public ILoggerFactory getLoggerFactory() { return loggerFactory; }
@Override public IMarkerFactory getMarkerFactory() { return markerFactory; }
@Override public MDCAdapter getMDCAdapter() { return mdcAdapter; }
@Override public String getRequestedApiVersion() { return REQUESTED_API_VERSION; }
@Override
public void initialize() {
loggerFactory = new TimbreLoggerFactory();
markerFactory = new BasicMarkerFactory();
mdcAdapter = new BasicMDCAdapter();
}

}
Loading

0 comments on commit 2ed6b43

Please sign in to comment.