, ,

Logback is designed to be faster and have a smaller memory footprint than the other logging frameworks around. If you are new to Logback, you should checkout my introductory post on Logback: Logback Introduction: An Enterprise Logging Framework.

Logback supports configuration through XML and Groovy. I explained XML configuration in my previous post, Logback Configuration: using XML. We’ll use similar configuration options for Logback, but this time in Groovy.

Because of its simplicity and flexibility, Groovy is an excellent tool for configuring Logback. Groovy is intuitive and has an easy-to-learn syntax. Even if you aren’t familiar with it, you should still easily understand, read, and write groovy configurations for Logback.

Creating a Logger

We will start by creating an application logger. As I mentioned in my earlier post here, for a Spring Boot application, we don’t need any additional Logback dependencies in our Maven POM. Groovy support is already there. We just need to start using it. Let’s start with creating a class and test for our example.

LogbackConfigGroovy.java

Our test class uses JUnit to unit test the LogbackConfigGroovy class.

LogbackConfigGroovyTest.java

The Groovy Configuration File

When Logback starts, it searches for a logback.groovy file in the classpath to configure itself. If you store the file in a different location outside the classpath, you will need to use the logback.configurationFile system property to point to the location, like this.

In a logback.groovy file, you can enable auto-scan using the scan() method. With auto-scan enabled, Logback scans for changes in the configuration file. For any changes, Logback automatically reconfigure itself with them. By default, Logback scans for changes once every minute. You can specify a different scanning period by passing a scan period, with a value specified in units of milliseconds, seconds, minutes or hours as parameter to scan(). For example, scan("30 seconds") tells Logback to scan Logback.groovy after every 30 seconds.

In logback.groovy, you can define one or more properties, like this.

Configuration code after a property declaration can refer the property with the ${property_name} syntax, as shown in the second line of the code above. If you’re familiar with Spring, you’ll find this syntax similar to SpEL.

Console and File Appenders

You declare one or more appenders with the appender() method. This method takes the name of the appender being configured as its first mandatory argument. The second mandatory argument is the class of the appender to instantiate. An optional third element is a closure, an anonymous block containing further configuration instructions.

The code to create a Logback console and a file appender, is this.

In the code above:

  • Line 1: We called the appender() method passing Console-Appender as the appender name and ConsoleAppender as the appender implementation class.
  • Line 2: We injected an encoder of type PatternLayoutEncoder into the appender.
  • Line 3: We set the pattern property of the encoder to the %msg%n conversion pattern. A conversion pattern is composed of literal text and format control expressions called conversion specifiers. You can learn more about pattern layout and conversion specifiers here.
  • Line 6 – Line 12: We created a file appender named File-Appender of the FileAppender type, and set the file property to a log file. We injected an encoder into the appender and set the pattern and outputPatternAsHeader properties of the encoder. The outputPatternAsHeader property, when set to true, inserts the pattern used for the log output at the top of log files.

We will now configure an application-specific logger along with the root logger to use the console and file appenders.

You use the logger() method to configure a logger. This method accepts the following parameters.

  • A string specifying the name of the logger.
  • One of the OFF, ERROR, WARN, INFO, DEBUG, TRACE, or ALL fields of the Level class to represent the level of the designated logger.
  • An optional List containing one or more appenders to be attached to the logger.
  • An optional Boolean value indicating additivity. The default value is true. We will come to additivity a bit later.

The code to configure the loggers is this.

In the code above, we configured all loggers of the guru.springframework.blog.Logbackgroovy package and its sub-packages to log INFO and higher level messages to the configured File-Appender. We also configured the root logger to log INFO and higher level messages to the configured Console-Appender.

The output on running the test class, LogbackConfigGroovyTest is this.
Output of Console and File Appender

Rolling File Appender

The rolling file appender supports writing to a file and rolls the file over according to one of your pre-defined policies. To learn more about the rolling file appender and its policies, refer to the Logback manual.

The code to configure a rolling file appender is this.

in the code above:

  • Line 1: We called the appender() method passing RollingFile-Appender as the appender name and RollingFileAppender as the appender class.
  • Line 2: We set the file property of the appender to specify the rolling file.
  • Line 3: We injected a time-based rolling policy of type TimeBasedRollingPolicy into the appender. A time-based rolling policy performs a rollover once the date/time pattern is no longer applies to the active log file.
  • Line 4 – Line 6: We set the fileNamePattern, maxHistory, and totalSizeCap properties of the policy. The fileNamePattern property defines a file name pattern for archived log files. The rollover period is inferred from the value of fileNamePattern, which in the code example is set for daily rolling. The maxHistory property sets the maximum number of archive files to keep, before deleting older files asynchronously. The totalSizeCap element sets the total size of all archive files. Oldest archives are deleted asynchronously when the total size cap is exceeded.

To use the rolling file appender, add the appender name in the list passed to the logger() method, like this.

At this point, if you run the test class, a rolling log file named rollingfile.log is created under logs. To simulate a rollover, you can set the system clock one day ahead and run the test class again. A new rollingfile.log is created under logs and the previous file is archived in the logs/archive folder.
Output of Rolling File Appender

Async Appender

An async appender runs in a separate thread to decouple the logging overhead from the thread executing your code. To make an appender async, first call the appender() method passing a name for the async appender and an AsyncAppender object. Then, inject the appender to invoke asynchronously, like this.

The code above makes the RollingFile-Appender appender asynchronous.

Once you define an async appender, you can use it in a logger like any other appender, as shown.

The complete code of the logback.groovy file is this.

Logback.groovy

In the configuration code above, observe Line 34. I included the console appender and passed a false parameter to logger(). I did this to disable additivity. With additivity disabled, Logback will use Console-Appender of the application logger instead of the one configured for the root logger. Review the Logback manual for more information on additivity. If you have noticed in the Groovy code, we intentionally skipped a number of import statements. To reduce unnecessary boilerplate code, Groovy includes several common types and packages by default.

Summary

If you work with both XML and Groovy to configure Logback, you will find the Groovy syntax less verbose, and so more readable. Also, the Groovy syntax being a super-set of Java syntax is more intuitive for Java developers. On the other hand, XML with the years of industry backing is more popular and have a larger user base. You’ll find better IDE support when using XML, since it can be validated against the structure of a XML schema. Groovy doesn’t have this fallback. So while you may be writing snytxually correct Groovy code, it may fail to configure Logback in the way in you intended.

The Logback team provides an online conversion tool to translate a Logback.xml file into the equivalent Logback.groovy configuration file. Although, you cannot expect 100% accuracy, It’s a good tool to use for reference.

Personally, I feel you should not lock yourself into XML or Groovy. XML will provide you highly structured configuration. Groovy gives you freedom to do things programmatically, which you cannot do in a structured XML document. Most of the time, XML configuration will be just fine. But when you have a complex use case for your logging requirements, Groovy is a great tool you can use to configure Logback.

0
Share
, ,

Polyglot Programming

Is the practice of programming in multiple programming languages. According to Wikipedia it is –

In computing, a polyglot is a computer program or script written in a valid form of multiple programming languages, which performs the same operations or output independent of the programming language used to compile or interpret it.

In writing the code for a recent blog post on Spring Integration, I thought it would be fun to write some of the code in Groovy. I’ve been writing in Groovy for about 7 years. I’m as fluent in Groovy as I am in Java, so its no problem for me to bounce between the two languages. If you been following my blog, you’ve probably seen me use Spock for my unit tests. Spock is a great tool. A Groovy testing framework for testing Java code.

Many Java developers who are not familiar with Groovy, view it as just a scripting language. Groovy is not just a scripting language. It is an Object Oriented Programming language, just like Java is. Some may argue that Groovy is a pure object oriented language and Java is not because of Java’s support of Primitive Types. Because unlike Java, Groovy does autoboxing of primitive types.

Its also important to understand, Groovy was never intended to be a replacement of Java. It’s written to supplement Java. As such, its very easy to mix and match code. Ultimately both Groovy and Java compile down to JVM byte code, and the compiled code is compatible.

Polyglot Programming in the Spring Framework

The Spring Framework is no stranger to Polyglot programming. The Grails community really spearheaded things with the Groovy language. In version 4 of the Spring Framework, we’re seeing a lot more support of polyglot programming around the Groovy language. But in the various Spring Framework projects we’re seeing more polyglot programming support around the Scala programming language. With Rod Johnson involved with Typesafe, I think it’s a safe bet we will see additional support of Scala in Spring in the future.

Groovy Spring Beans

It is possible to write Spring Beans in Groovy. Your application will compile and run just fine. Whenever programming for Dependency Injection, I recommend developing your code to an interface.

AddressService

When doing polyglot programming, I prefer to write the interface in Java. Now any class, written in Java or Groovy can implement the interface. You probably could write the interface in Groovy and use it in Java just fine, but there are some pitfalls of using Groovy from Java you need to be aware of. For example if you use ‘ def ‘ as a type, Java treats it as a Object  data type. Sometimes the strong typing of Java is not a bad thing. This also seems more appropriate to me when defining the interface to use.

AddressServiceImpl.groovy

You can see my Groovy class simply implements the AddressService  interface. I mark the class with the @Service("addressService")  annotation as I would a normal Java Spring Bean. 

Using a link below, you can checkout the full project. You will see the Groovy class compiles with the Java code and runs in the Spring context like any other Spring Bean.

Conclusion

In enterprise Java / Spring shops, you probably will not see much Polyglot programming. But, the Grails team uses Groovy for Spring Beans all the time. I’ve demonstrated its easy to use Groovy Spring beans outside of the Grails environment. This is not a technology issue to overcome. Culturally, I suspect it may be some time before you see polyglot programming in large scale enterprise applications. But doing polyglot programming like this is something fun to do in blog posts!

Get The Code

I’ve committed the source code for this post to github. It is a Maven project which you can download and build. If you wish to learn more about the Spring Framework, I have a free introduction to Spring tutorial. You can sign up for this tutorial in the section below.

Source Code

The source code for this post is available on github. You can download it here.

0
Share