Adding a custom field in log4j using SyslogAppender - java

I'm using the SyslogAppender in my java application and I'm trying to add a custom field to the resulting log. How can I add an additional field to my log4j.properties?
My current log4j.properties (the last line shows what I want to achieve):
log4j.appender.SYSLOG=org.apache.log4j.net.SyslogAppender
log4j.appender.SYSLOG.threshold=INFO
log4j.appender.SYSLOG.syslogHost=localhost
log4j.appender.SYSLOG.facility=LOCAL4
log4j.appender.SYSLOG.header=true
log4j.appender.SYSLOG.layout=org.apache.log4j.PatternLayout
log4j.appender.SYSLOG.layout.conversionPattern=my-app: %m%n
log4j.appender.SYSLOG.applicationName=${STACKNAME}
The ${STACKNAME} is a system property configured by the deployment job, depending on the environment (e.g. prod, test, dev).

From this answer I get the answer: add the lines
log4j.appender.graylog2.additionalFields={'filed_name': 'field_value', 'field2_name': 'field2_value'}
log4j.appender.graylog2.addExtendedInformation=true
to add field_name and field2_name with values field_value and field2_value. The property addExtendedInformation=true indicates Graylog to add those fields to all log entries.

Related

Logback java configuration in runtime

I need create a lot of .log file in different folders from one java method.
Example:
home/work/folder1/log1.log
home/work/folder1/log2.log
home/work/folder2/log3.log
...............................
In java method i create dynamic Logger:
private Logger getLogger(String extId, String workId) {
String postfix = String.join(
".",
getClass().getName(),
extId, //folder1, folder2
String.valueOf(workId) //log1, log2
);
return LoggerFactory.getLogger(postfix);
}
How i can configurate logback to runtime create files?
I see ch.qos.logback.classic.spi.Configurator, but don't inderstand what do next.
Thank for any helps!
Why do you care about your log folders?
You can log in one folder and use the elk-stack to verify them.
I always do it with one sperate folder per log level and configure my logpattern with log4j2. Logstash reads the logs immediatly when new ones are available und pushes them to elastic search. With kibana you can do many cool dashboards to analyze them.

vertx LoggerHandler not adding logback

I am trying to use LoggerHandler to log all incoming requests. I am using logback.xml to specify appenders. I am setting system property for logging.
System.setProperty("org.vertx.logger-delegate-factory-class-name",
"org.vertx.java.core.logging.impl.SLF4JLogDelegateFactory");
Still it is logging everything in console not in file.
This worked for me with Vert.x 3.4.1:
import static io.vertx.core.logging.LoggerFactory.LOGGER_DELEGATE_FACTORY_CLASS_NAME;
import io.vertx.core.logging.LoggerFactory;
// ...
setProperty (LOGGER_DELEGATE_FACTORY_CLASS_NAME, SLF4JLogDelegateFactory.class.getName ());
LoggerFactory.getLogger (LoggerFactory.class); // Required for Logback to work in Vertx
The key is to get a logger, which I guess initializes the Logging subsystem, the class that you use to get a Logger seems irrelevant as I tried with two different ones.
I run these lines as the first ones of the program in production code and in the tests to work properly in both contexts.
I was able to get it to work by setting the VM options as such:
-Dvertx.logger-delegate-factory-class-name=io.vertx.core.logging.Log4jLogDelegateFactory
Then in my log4j.properties, I had to add this:
log4j.category.io.vertx = TRACE
I know this question is getting a bit old, but the only way I was able to get the vertx LoggerHandler to not use JUL was to call LoggerFactory.initialise() after setting the system property as described in the question.
Even better, I set the property in my build.gradle, like so:
run {
systemProperty(
"vertx.logger-delegate-factory-class-name",
"io.vertx.core.logging.SLF4JLogDelegateFactory"
)
args = ['run', mainVerticleName, "--redeploy=$watchForChange", "--launcher-class=$mainClassName", "--on-redeploy=$doOnChange",
"-Dvertx.logger-delegate-factory-class-name=io.vertx.core.logging.SLF4JLogDelegateFactory" ]
}
And then at the very top of my MainVerticle::start I have:
LoggerFactory.initialise()
And, boom. Everything is now formatted correctly, including all the startup output.

Unable to set log level in a Java web start application?

Some logging levels appear to be broke?
I run a Java web start (which I will begin to call JWS from now on) application straight from a GlassFish 3.1.2.2 instance. The client has a static logger like so:
private final static Logger LOGGER;
static {
LOGGER = Logger.getLogger(App.class.getName());
// Not sure how one externalize this setting or even if we want to:
LOGGER.setLevel(Level.FINER);
}
In the main method, I begin my logic with some simple testing of the logging feature:
alert("isLoggable() INFO? " + LOGGER.isLoggable(Level.INFO)); // Prints TRUE!
alert("isLoggable() FINE? " + LOGGER.isLoggable(Level.FINE)); // ..TRUE
alert("isLoggable() FINER? " + LOGGER.isLoggable(Level.FINER)); // ..TRUE
alert("isLoggable() FINEST? " + LOGGER.isLoggable(Level.FINEST)); // ..FALSE
My alert methods will display a JOptionPane dialog box for "true GUI logging". Anyways, you see the printouts in my comments I added to the code snippet. As expected, the logger is enabled for levels INFO, FINE and FINER but not FINEST.
After my alert methods, I type:
// Info
LOGGER.info("Level.INFO");
LOGGER.log(Level.INFO, "Level.INFO");
// Fine
LOGGER.fine("Level.FINE");
LOGGER.log(Level.FINE, "Level.FINE");
// Finer
LOGGER.finer("Level.FINER");
LOGGER.log(Level.FINER, "Level.FINER");
LOGGER.entering("", "Level.FINER", args); // <-- Uses Level.FINER!
// Finest
LOGGER.finest("Level.FINEST");
LOGGER.log(Level.FINEST, "Level.FINEST");
I go to my Java console and click on the tab "Advanced", then I tick "Enable logging". Okay let's start the application. Guess what happens? Only Level.INFO prints! Here's my proof (look at the bottom):
I've done my best to google for log files on my computer and see if not Level.FINE and Level.FINER end up somewhere on the file system. However, I cannot find the log messages anywhere.
Summary of Questions
Why does it appear that logging of Level.FINE and Level.FINER does not work in the example provided?
I set the logging level in my static initializing block, but I'd sure like to externalize this setting to a configuration file of some sort, perhaps packaged together with the EAR file I deploy on GlassFish. Or why not manually write in some property in the JNLP file we download from the server. Is this possible somehow?
Solution for problem no 1.
After doing a little bit more reading on the topic, I concluded that a logger in Java uses a handler to publish his logs. And this handler in his turn has his own set of "walls" for what levels he handles. But this handler need not be attached directly to our logger! You see loggers are organized in a hierarchical namespace and a child logger may inherit his parents handlers. If so, then By default a Logger will log any output messages to its parent's handlers, and so on recursively up the tree (see Java Logging Overview - Oracle).
I ain't saying I get the full picture just yet, and I sure didn't find any quotes about how all of this relates to a Java Web Start application. Surely there has to be some differences. Anyways, I did manage to write together this static initializing block that solves my immediate problem:
static {
LOGGER = Logger.getLogger(App.class.getName());
/*
* This logic can be externalized. See the next solution!
*/
// DEPRECATED: LOGGER.setLevel(Level.FINER);
if (LOGGER.getUseParentHandlers())
LOGGER.getParent().getHandlers()[0].setLevel(Level.FINER);
else
LOGGER.setLevel(Level.FINER);
}
Solution for problem no 2.
The LogManager API docs provided much needed information for the following solution. In a subdirectory of your JRE installation, there is a subdirectory called "lib" and in there you shall find a "logging.properties" file. This is the full path to my file on my Windows machine:
C:\Program Files (x86)\Java\jre7\lib\logging.properties
In here you can change a lot of flavors. One cool thing you could do is to change the global logging level. In my file, this was done on row 29 (why do we see only a dot in front of the "level"? The root-parent of all loggers is called ""!). That will produce a hole lot of output; on my machine I received about one thousand log messages per second. Thus changing the global level isn't even plausible enough to be considered an option. Instead, add a new row where you specify the level of your logger. In my case, I added this row:
martinandersson.com.malivechat.app.App.level = FINER
However, chances are you still won't see any results. In solution no 1, I talked about how loggers are connected to handlers. The default handler is specified in logging.properties, most likely on row 18. Here's how my line reads:
handlers= java.util.logging.ConsoleHandler
Also previously, I talked about how these handlers in their turn use levels for what should trouble their mind. So, find the line that reads something like this (should now be on row 44?):
java.util.logging.ConsoleHandler.level = INFO
..and in my case I swapped "INFO" to "FINER". Problem solved.
But!
My original inquiry into this matter still hasn't provided an answer how one can set these properties closer in par with the application deployment. More specifically, I would like to attach these properties in a separate file, bundled with the application EAR file I deploy on GlassFish or something like that. Do you have more information? Please share!

How to set values to placeholders in log4j.properties file?

I am using spring/hibernate application. i am using log4j for logging. the problem is i need to place a placeholder in log4j.properties file and i need to set the value to the place holder based on the environment(Dev, UAT or Production).
Environment=${environment}
is it possible? Please help me.
Thanks!
You can pass the variable and value either by command line or set environment variable like below.
-DEnvironment=dev
then you can use this in log file like :
Environment=${Environment}
Why not just use seperate keys, and pick the right one at runtime?
Environment.dev=Development
Environment.prod=Production
Environment.qa=QA
bundle.getKey(ENVIRONMENT_KEY_PREFIX + ".dev");

log4j - set different loglevel for different packages/classes

I use log4j for logging and i want to print all logger.debug statements in a particular class / selected package.
i set the cfg as below>
log4j.category.my.pkg=info
log4j.category.my.pkg.ab.class1=debug
but still only info messages are shown..
is this not the right way ?
Instead of using 'category' use 'logger'. Hence, these level are configured for entire log4j, and does not depend on appender, etc.
Following change works:
log4j.logger.my.pkg=info
log4j.logger.my.pkg.ab.class1=debug
Copying from my current log4j.properties:
log4j.logger.org.hibernate.tool.hbm2ddl=warn
log4j.logger.org.hibernate.sql=info

Categories