Vert.x: best way to log to file - java

What is the fastest async way to log to file in Vert.x?
The aim is to write logs from loggers from different classes (i.e. Class1, Class2 etc) to 1 file (something like 'console.log')

Vert.x uses the JDK bundled JUL logging framework to avoid shipping additional dependencies. However it allows to append a custom logger implementation.
Assuming that you want to stick to the default logging facility, customizing the log handler would then be as easy as droping a logging file and referencing it through the java.util.logging.config.file system property:
For example you can drop the logging configuration file under a config directory under the root path of your (fat) jar which may look as follows:
handlers = java.util.logging.MyFileHandler
config =
#...
You should then refrence that file in a system property as follows when starting your Vert.x application:
-Djava.util.logging.config.file=config/logging.properties
You can then access the Logger object in your classes as follows:
Logger logger = LoggerFactory.getLogger("some.package.MyClass");
Use that logger to log messages that will be handled by the configured handler(s):
logger.info("some informative message");
Note the use of a custom log handler in the properties file to emphasis the possibily of appending your own handler (which may extend the default FileHandler).
Check the Vert.x documentation for more informations on how to use explore the logging feature.

Most of loggers are async from the beginning , i.e. they are not write information immediately. Logs are stored into buffer, which is flushed by timeout or when it is full. So slf4j + log4 is good enough for most cases.

Related

How to configure IBM WAS SystemOut logging to customize logging for each application?

I have 4 appllications (ear) on my WAS. I need them to write in SystemOut.log some sign. I.e each application must write to log file its own sign. For example:
[16.01.17 3:50:05:592 GMT+05:00] ADMIN 000005e0 SubsystemMess I com.docflow.core.integration.jms.SubsystemMessageListener onMessage_aroundBody0 Subsystem integration message ID:f5392a5ec3b3f41502095b00110a134f0000000000000001 of type DP_EKS_BANK_GUARANTEE_RECEIVED process finished
Here ADMIN is sign of the application.
How i can do that?
It's not possible to adjust the default logging format in this way. Your options would be to use java.util.logging.Logger with a particular name (to replace the "SubsystemMess" part) or to use a separate logging package and configure it to log to a separate file.
Look at log4j and configuring each app's log4j to go to a different file.
Log4j's file appender can be configured to also include timestamp and more.
The only catch is you can't configure it from WAS's admin console then.
Note that java.util.Logger writes to the trace.log. If you use a different logger name, it will list as such in the same trace.log file. Upside is you can now configure it from the admin console.
One potential solution could be to switch to HPEL logging. Then you could query log entries for your given application using logviewer, like:
logViewer.sh -includeExtensions appName=PlantsByWebSphere
I know that it is not exactly what you are looking for, but maybe it will be sufficient for your needs.

Multiple log4j.xml in a jar files

I am developing a client api where I have a specific requirement to log the client api specific log messages to a separate file and it is pretty straight forward: I created an appender and associated the appender with logger which is specific to my package.
Now the question is:
What happens if the client application has its own log4j.xml? How will my appender and logger work in that environment ?
The log4j initialization process only handles one configuration file - thus this file should contain all logging configuration that should be active. You probably have to define a specific configuration for the client application that contains your and the client applications logging configuration.
The client application has to be configured to use this file for the initialization. This is done by setting the log4j.configuration system property as described in the log4j manual (suppose that you are using log4j 1).

LOG4j - ways to configure it

I'd like to configure log4j in a huge distributed system. There are a lot of JVMs and processes and (as I am only a student) I am new to such a situation. I use JMS Appender, so I need two files: log4j.properties, jndi.properties.
I've tried some ways:
Put these files into src folder
or into src/java
add jvm argument -Dlog4j.configuration=C:\...\log4j.properties
I don't want to set it in code using PropertyConfigurator.configure("path"), because I'd like to not change source code at all.
Are there any other ways to configure log4j? Or maybe I am missing something? I still get a messages
No appenders could be found for logger (some.package.SomeClass).
Please initialize the log4j system properly.
basically you have the following ways to configure Log4J:
Via your code
properties file (as you're trying to use)
Xml File
What you're asking to me related to specific configuration of JMS appender and its not about 'general way of how to configure log4j'
Here is an example of how to configure it with ActiveMQ
For other JMS implementations in your property file the keys will be probably the same but the values will be different
Example - using JMS appender with ActiveMQ

How can I log that a log file is newly created?

I've been given the requirement that the first line of my log files must begin with a specific header. This header should specify that this current file is newly created. Even when log files are automatically rotated.
It seems odd but it is in the specification for the project.
Environment info:
App Server: Glassfish V2
Logging: SL4J
I think you're going to have to subclass the relevant appender and add your own code to do this.
The log file is not written by slf4j. It is written by the logging system behind the facade. The solution will depend on what that logging system is.
Unless that logging system has an existing log file appender that does this, you will need to write a custom appender (using the appropriate API, etc) that writes the header each time it opens a new log file.

Log(ger) Variable Declaration

In the majority of cases I see Log instances declared as follows:
public static final Log LOG = LogFactory.getLog(MyClass.class);
I assume this means that the log configuration is loaded when the MyClass is loaded and is therefore set in stone until the MyClass is either reloaded or the JVM restarted?
So, if this assumption is correct what is the best way to ensure changes to the log configuration are picked up as (or as soon after) they happen?
I assume that you are using commons-logging from the LogFactory class? As far as I know, none of the usual logging implementations (Log4J, java.util.logging) allow you to reload a configuration file in a running application (regardless of whether the actuall Loggers are declared as static variables). (EDIT: Peter's answer below proves that I was wrong about this in the case of Log4J)
However, they do allow for the dynamic changing of logging levels (e.g. via an MBean). These level-changes will be picked up by any Logger (including those declared as static variables). If you use java.util.logging you get the MBean for free in the JConsole.
Is it just the changing of levels you care about, or do you wish to provide completely different logging configurations (e.g. files, logger definitions) on the fly?
I guess this depends on the underlying implementation, as pointed out by oxbow_lanes. Generally, it might be difficult to reconfigure your logging subsystem if you are relying on config files that are available via the classpath. To get around this limitation, we do all our config programmatically, and do not rely on only static config files. But I don't know whether your implementation support programmatic reconfiguration.
No, the log configuration is loaded typically when the logging implementation classes are initialized. When your class is (re)loaded, all that happens is that the logging API is called to get a logger (which may or may not be present in any configuration) and stored as a class variable.
To reload your logging configuration, then you typically would have to get the logging implementation to reload.
Depends on the backend.
Logback has a very niftly feature where the reload can be triggered by JMX, i.e. in jvisualvm or jconsole.
Actually, if you are using "java.util.logging" logging directly, then you CAN reload the logger configurations on the fly. There are two methods on the LogManager class for doing this:
public void readConfiguration()
throws IOException, SecurityException
This reloads the default logging properties and reinitializes the logging configuration.
public void readConfiguration(InputStream ins)
throws IOException, SecurityException
This loads the logging properties from a stream (in Property file format) and reinitializes the logging configuration.
See the LogManager javadoc.
Log4j can reload your config file whenever it changes.
see the faq here
Is there a way to get log4j to
automatically reload a configuration
file if it changes?
Yes. Both the DOMConfigurator and the
PropertyConfigurator support automatic
reloading through the
configureAndWatch method. See the API
documentation for more details.
Because the configureAndWatch launches
a separate wathdog thread, and because
there is no way to stop this thread in
log4j 1.2, the configureAndWatch
method is unsafe for use in J2EE
envrironments where applications are
recycled.

Categories