DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
View Events Video Library
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Integrating PostgreSQL Databases with ANF: Join this workshop to learn how to create a PostgreSQL server using Instaclustr’s managed service

Mobile Database Essentials: Assess data needs, storage requirements, and more when leveraging databases for cloud and edge applications.

Monitoring and Observability for LLMs: Datadog and Google Cloud discuss how to achieve optimal AI model performance.

Automated Testing: The latest on architecture, TDD, and the benefits of AI and low-code tools.

Related

  • Surviving the Incident
  • Polymorphism and Dynamic Binding in Java
  • Detect Log4j Vulnerability Using ACS
  • How To Detect and Secure Your Java App From Log4j Vulnerabilities

Trending

  • Unleashing the Power of Microservices With Spring Cloud
  • Creating a Deep vs. Shallow Copy of an Object in Java
  • Parallelism in ConcurrentHashMap
  • TypeScript: Useful Features
  1. DZone
  2. Coding
  3. Java
  4. SLF4J Binding for ADFLogger - the Missing Piece

SLF4J Binding for ADFLogger - the Missing Piece

Arun Manivannan user avatar by
Arun Manivannan
·
Nov. 07, 13 · Interview
Like (0)
Save
Tweet
Share
5.30K Views

Join the DZone community and get the full member experience.

Join For Free

For reasons best left untold, in my day job, I was expected to provide an SLF4J Adapter for ADF Logger Oracle ADF. Not surprisingly, slf4j does not have an adapter for ADFLogger but since ADFLogger was just a gentle wrapper over Java Util Logging, it took a little over an hour to fill that gap.

The testcases (more like main programs) in the repository will confirm that the adapter framework plays well with the Oracle Diagnostic Logging –without breaking the format of the log messages. (which is more or less the only advantage which the ADFLogger provides).

You could download the entire codebase from the repository at github. Optionally, if you are interested only in the binding jar, please download it here.

Log Levels :

Considering there are many log levels on the ADF Logger (7) and fewer levels in SLF4J (5), a compromise was made on certain levels on the ADF Logger. The mapping is made as follows :

NOTE : Support for Log levels FINER and CONFIG were dropped during this adaptation.

Usage :

Just go ahead and replace your ADFLogger with SLF4J instantiations.

private static final Logger slfLogger = LoggerFactory.getLogger(LoggingChecker.class);

instead of

private static final ADFLogger adfLogger= ADFLogger.createADFLogger(LoggingChecker.class);

Logging methods

a. Logging to various levels

@Test
  public void testLoggerLevels(){
        adfLogger.finest("finest Message from ADF Logger");
        slfLogger.trace("finest Message from SLF Logger");
        adfLogger.fine("fine Message from ADF Logger");
        slfLogger.debug("fine Message from SLF Logger");
        adfLogger.info("info Message from ADF Logger");
        slfLogger.info("info Message from SLF Logger");
        adfLogger.warning("warning Message from ADF Logger");
        slfLogger.warn("warning Message from SLF Logger");
        adfLogger.severe("severe Message from ADF Logger");
        slfLogger.error("severe Message from SLF Logger");
     }

b. Logging exceptions

 where dummyException inherits a Throwable

c. Logging parameters

Development Notes :

  1. The ADF Logger Adapter framework composes of two core classes (the ADFLoggerFactory.java and the ADFLoggerAdapter.java) and three other helper classes.
  2. The Adapter can support multiple loggers including the ROOT logger of the ADFLogger (which is the default and has an empty string as its name).
  3. It is no surprise that SLF4J uses the ADFLoggerFactory.java to instantiate the ADFLoggerAdapter.
  4. For each Logger instance, the ADFLoggerAdapter.java composes an instance of ADFLogger (bound to the logger name) and delegates the call to the ADFLogger itself.
  5. The fillCallerData method of the ADFLoggerAdapter.java filters the stackframes of the ADFLoggerAdapter from the entire logging stack so that the caller class and method name is retained as the one from the host application and not of the Adapter framework classes.

Testcase (well, sort of)

public class TestClass {
    private static final ADFLogger adfLogger= ADFLogger.createADFLogger(TestClass.class);
    private static final Logger slfLogger = LoggerFactory.getLogger(TestClass.class);
    private List<String> dummyList1=null;
    private List<Integer> dummyList2=null;
    private Exception dummyException=null;
    @Before
    public void setUp(){
      dummyList1=new ArrayList<String>();
      dummyList1.add("Rock");
      dummyList1.add("Paper");
      dummyList1.add("Scissors");
      dummyList2=new ArrayList<Integer>();
      dummyList2.add(21);
      dummyList2.add(22);
      dummyList2.add(23);
      dummyException=new Exception("Mind blowing Exception");
    }
    @Test
  public void testLoggerLevels(){
        adfLogger.finest("finest Message from ADF Logger");
        slfLogger.trace("finest Message from SLF Logger");
        adfLogger.fine("fine Message from ADF Logger");
        slfLogger.debug("fine Message from SLF Logger");
        adfLogger.info("info Message from ADF Logger");
        slfLogger.info("info Message from SLF Logger");
        adfLogger.warning("warning Message from ADF Logger");
        slfLogger.warn("warning Message from SLF Logger");
        adfLogger.severe("severe Message from ADF Logger");
        slfLogger.error("severe Message from SLF Logger");
  }
    @Test
      public void testException(){
          adfLogger.severe("severe Message from ADF Logger", dummyException);
          slfLogger.error("severe Message from SLF Logger", dummyException);
      }
    @Test
      public void testParameters(){
          adfLogger.severe("severe Message from ADF Logger Param :{0}", dummyList1 );
          slfLogger.error("severe Message from SLF Logger Param :{}", dummyList1);
          adfLogger.severe("severe Message from ADF Logger Param 1 :[{0}] \n [{1}]", new Object[]{dummyList1, dummyList2} );
          slfLogger.error("severe Message from SLF Logger Param :{} \n {} ", dummyList1, dummyList2);
          slfLogger.error("severe Message from SLF Logger Param :[{}] \n [{}] ", new Object[]{dummyList1, dummyList2});
      }

Output :

Logger levels :

Jul 01, 2013 4:21:18 PM org.slf4j.test.TestClass testLoggerLevels
INFO: info Message from ADF Logger
Jul 01, 2013 4:21:18 PM org.slf4j.test.TestClass testLoggerLevels
INFO: info Message from SLF Logger
Jul 01, 2013 4:21:18 PM org.slf4j.test.TestClass testLoggerLevels
WARNING: warning Message from ADF Logger
Jul 01, 2013 4:21:18 PM org.slf4j.test.TestClass testLoggerLevels
WARNING: warning Message from SLF Logger
Jul 01, 2013 4:21:18 PM org.slf4j.test.TestClass testLoggerLevels
SEVERE: severe Message from ADF Logger
Jul 01, 2013 4:21:18 PM org.slf4j.test.TestClass testLoggerLevels
SEVERE: severe Message from SLF Logger

Testing Parameters :

Jul 01, 2013 4:32:04 PM org.slf4j.test.TestClass testParameters
SEVERE: severe Message from ADF Logger Param :[Rock, Paper, Scissors]
Jul 01, 2013 4:32:04 PM org.slf4j.test.TestClass testParameters
SEVERE: severe Message from SLF Logger Param :[Rock, Paper, Scissors]
Jul 01, 2013 4:32:04 PM org.slf4j.test.TestClass testParameters
SEVERE: severe Message from ADF Logger Param 1 :[[Rock, Paper, Scissors]]
 [[21, 22, 23]]
Jul 01, 2013 4:32:04 PM org.slf4j.test.TestClass testParameters
SEVERE: severe Message from SLF Logger Param :[Rock, Paper, Scissors]
 [21, 22, 23]
Jul 01, 2013 4:32:04 PM org.slf4j.test.TestClass testParameters
SEVERE: severe Message from SLF Logger Param :[[Rock, Paper, Scissors]]
 [[21, 22, 23]]

Testing Exception :

Jul 01, 2013 4:32:28 PM org.slf4j.test.TestClass testException
SEVERE: severe Message from ADF Logger
java.lang.Exception: Mind blowing Exception
  at org.slf4j.test.TestClass.setUp(TestClass.java:38)
  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
  at java.lang.reflect.Method.invoke(Unknown Source)
  at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
  at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
  at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
  at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:27)
  at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
  at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
  at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
  at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
  at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
  at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
  at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
  at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
  at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
  at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
  at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
  at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
  at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
  at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
  at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Jul 01, 2013 4:32:28 PM org.slf4j.test.TestClass testException
SEVERE: severe Message from SLF Logger
java.lang.Exception: Mind blowing Exception
  at org.slf4j.test.TestClass.setUp(TestClass.java:38)
  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
  at java.lang.reflect.Method.invoke(Unknown Source)
  at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
  at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
  at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
  at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:27)
  at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
  at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
  at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
  at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
  at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
  at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
  at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
  at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
  at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
  at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
  at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
  at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
  at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
  at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
  at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Log4j Binding (linguistics)

Published at DZone with permission of Arun Manivannan, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Surviving the Incident
  • Polymorphism and Dynamic Binding in Java
  • Detect Log4j Vulnerability Using ACS
  • How To Detect and Secure Your Java App From Log4j Vulnerabilities

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends: