Parameterised logging in Jython?

Tags: #<Tag:0x00007f5c9820fd68>

How do you do parameterised logging in Jython? I’ve been doing this:

functionname.log.debug("Hello {}!".format("world"))

But I have a feeling that this isn’t the same as parameterised logging because I would think that this gets parsed / executed regardless of the enabled logging level. In other words, isn’t this just python’s string formatting?

So how can I do the equivalent of Java’s / Xtend’s parameterised logging?

https://openhab-scripters.github.io/openhab-helper-libraries/Guides/Logging.html

Yes, for the message itself. Logging setup determines the prefix, though, and if/when to get logged.

@mstormi

I am aware of logging levels. That’s not what I am asking about here. Just to clarify, this is what I was referring to, and wanting to know how to do it in jython:

http://www.slf4j.org/faq.html#logging_performance

What is the fastest way of (not) logging?

SLF4J supports an advanced feature called parameterized logging which can significantly boost logging performance for disabled logging statement.

For some Logger logger , writing,

logger.debug("Entry number: " + i + " is " + String.valueOf(entry[i]));

incurs the cost of constructing the message parameter, that is converting both integer i and entry[i] to a String, and concatenating intermediate strings. This, regardless of whether the message will be logged or not.

One possible way to avoid the cost of parameter construction is by surrounding the log statement with a test. Here is an example.

if(logger.isDebugEnabled()) {
logger.debug("Entry number: " + i + " is " + String.valueOf(entry[i]));
}

This way you will not incur the cost of parameter construction if debugging is disabled for logger . On the other hand, if the logger is enabled for the DEBUG level, you will incur the cost of evaluating whether the logger is enabled or not, twice: once in debugEnabled and once in debug . This is an insignificant overhead because evaluating a logger takes less than 1% of the time it takes to actually log a statement.

Better yet, use parameterized messages

There exists a very convenient alternative based on message formats. Assuming entry is an object, you can write:

Object entry = new SomeObject();
logger.debug(“The entry is {}.”, entry);

After evaluating whether to log or not, and only if the decision is affirmative, will the logger implementation format the message and replace the ‘{}’ pair with the string value of entry . In other words, this form does not incur the cost of parameter construction in case the log statement is disabled.

The following two lines will yield the exact same output. However, the second form will outperform the first form by a factor of at least 30, in case of a disabled logging statement.

logger.debug(“The new entry is “+entry+”.”);
logger.debug(“The new entry is {}.”, entry);

A two argument variant is also available. For example, you can write:

logger.debug(“The new entry is {}. It replaces {}.”, entry, oldEntry);

If three or more arguments need to be passed, you can make use of the Object... variant of the printing methods. For example, you can write:

logger.debug(“Value {} was inserted between {} and {}.”, newVal, below, above);

This form incurs the hidden cost of construction of an Object[] (object array) which is usually very small. The one and two argument variants do not incur this hidden cost and exist solely for this reason (efficiency). The slf4j-api would be smaller/cleaner with only the Object… variant.

Array type arguments, including multi-dimensional arrays, are also supported.

SLF4J uses its own message formatting implementation which differs from that of the Java platform. This is justified by the fact that SLF4J’s implementation performs about 10 times faster but at the cost of being non-standard and less flexible.

Python’s string formatting is not parameterized logging.