I have implemented java.util.logging.Handler (LogHandler) and my Wildfly configuration is pretty much vanilla. Everything is fine and works as expected. The idea is now, to split the logging part into two files. What I have done is the following:
<periodic-rotating-file-handler name="PROTOCOL" autoflush="true">
<level name="INFO"/>
<formatter>
<named-formatter name="PATTERN"/>
</formatter>
<file relative-to="jboss.server.log.dir" path="protocol.log"/>
<suffix value=".yyyy-MM-dd"/>
<append value="true"/>
</periodic-rotating-file-handler>
...
<logger category="com.test.transport" use-parent-handlers="false">
<level name="INFO"/>
<handlers>
<handler name="PROTOCOL"/>
<handler name="CONSOLE"/>
</handlers>
</logger>
Works as expected as well, I got another file with the log from com.test.transport.
My problem is, since I have changed my wildfly configuration, everything in the PROTOCOL log file does not get published by my LogHandler.
Edit:
#Singleton
#Startup
public class LogHandler extends ExtHandler {
#Override
public void publish(LogRecord record) {
String message = record.getMessage();
}
}
If you're just looking to split your application log messages into a separate file what you have, minus your LogHandler should do that.
If you want to use your own log handler you need to install it as a module. See the CLI module add --help for details. There is no way to have custom handlers in your deployment. They need to be defined as modules.
You then need to add the handler as a custom-handler to the logging subsystem.
Here's some example commands to add the module and create the custom handler.
module add --name=com.test.transport --resources=/path/to/jar/transport-logging.jar
/subsystem=logging/custom-handler=PROTOCOL:add(class=com.test.transport.LogHandler, module=com.test.transport, level=INFO, named-formatter=PATTERN, properties={file="${jboss.server.log.dir}/protocol.log"})
/subsystem=logging/logger=com.test.transport:add(level=INFO, use-parent-handlers=false, handlers=[CONSOLE, PROTOCOL])
Related
I'm looking at the source code of some application. It is using Spring framework, Apache Tiles, JSP, Log4j, java, javascript, jquery, jqplot, Jsch, and etc.
I know where the logs are created. (a/b/logs) However, when I look at source code, I don't know how logs are created under the folder name 'logs'. I looked at log4j.xml, web.xml , property files. I found the code for how the path 'a/b' is created, but not logs. Also that folder has 4 types of logs. And they are name in a pattern like access.20181227001 , errors.20182111. I want to know where I have to look to find how the logs are created in this manner.
Log4J.xml
<!-- Appenders -->
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %5p [%c] %m%n" />
</layout>
</appender>
<appender name="console-infolog" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %5p %m%n" />
</layout>
</appender>
<!-- Application Loggers -->
<logger name="com.dsmentoring.chakan" additivity="false">
<level value="debug" />
<appender-ref ref="console"/>
</logger>
<!-- 3rdparty Loggers -->
<logger name="org.springframework.core">
<level value="error"/>
</logger>
<!-- Bean logger -->
<logger name="org.springframework.beans">
<level value="error"/>
</logger>
<!-- Context logger -->
<logger name="org.springframework.context">
<level value="error"/>
</logger>
<!-- Web logger -->
<logger name="org.springframework.web">
<level value="error"/>
</logger>
<logger name="org.springframework.ldap" additivity="true">
<level value="error"/>
</logger>
<!-- LDAP logger -->
<logger name="com.unboundid.ldap" additivity="true">
<level value="error"/>
</logger>
<!-- Root Logger -->
<root>
<priority value="off" />
<appender-ref ref="console" />
</root>
To sum up :
1) Is there a way to configure where logs are created and how they are created (4 types of logs) Other than log4j.xml, xml files and property files? I looked at all the java, jsp, js code but can't seem to find the configuration for logs. So I want to know if there are other ways to do that or where I should look for those configuration.
2) The 'logs' folder is possibly default for log4j?
ldap.properties
#LDAP Connection Info
ldap.host=192.168.0.17
ldap.port=22389
ldap.userName=cn=directory manager
ldap.password= 9074B18A0DE2D50C068D37B60BE5DFDE
ldap.baseDN=o=sso30root
ldap.defaultLoadSize=1000
ldap.start=start-ds
ldap.stop=stop-ds
ldap.workdir=/home/KB_openDJ // logs are created under this path
// /home/KB_openDJ/logs
In other java class, they use this.
#Value("${ldap.workdir}")
private String WORK_DIR;
// I ommited many lines in between
try{
diskUsage = sigar.getFileSystemUsage(WORK_DIR);
diskIOInfo.setDiskRead((int)(diskUsage.getDiskReadBytes()));
diskIOInfo.setDiskWrite((int)(diskUsage.getDiskWriteBytes()));
}catch(SigarException sigarEx){
log.debug("Disk Usage info load Error : " + sigarEx.getMessage());
}
I used the 'Search' feature in Eclipse many times. ( logs, WORK_DIR, and 4 types of log name, and many others. I am unable to locate the code about logging configuration. :(
My log4j version :
1.2.15
Ok, it seems that there's a solution which might help you. It requires some debugging of static initalization block of org.apache.log4j.LogManager class. This class is responsible for loading logger configuration file. Here's a documention link which thoroughly describes initalization process: link.
Here's an excerpt from a LogManager source file:
String configurationOptionStr = OptionConverter.getSystemProperty(DEFAULT_CONFIGURATION_KEY, null);
String configuratorClassName = OptionConverter.getSystemProperty(CONFIGURATOR_CLASS_KEY, null);
What I'm trying to show you here, is that your logger configuration file might be specified as a JVM option supplied to your application-server. That's why you are not able to determine actual file being used.
Even if this approach fails, I'd recommend you to investigate the appenders list retrieved at run-time. Here's a stackoverflow thread which describes how to do so: link.
We am using JBoss 7 in our project and have written the logging configuration in standalone.xml file like this,
<subsystem xmlns="urn:jboss:domain:logging:1.0">
.
.
.
<logger category="com.xyz.abc.aspect">
<level name="DEBUG"/>
<handlers>
<handler name="FILE"/>
</handlers>
</logger>
.
.
</subsystem>
Now a situation has arose that i wanted to change the logging configuration by adding use-parent-handlers="false" to avoid the log being redirected to parent handler , now when i add this to standalone.xml
<logger category="com.xyz.abc.aspect" use-parent-handlers="false">
<level name="DEBUG"/>
<handlers>
<handler name="FILE"/>
</handlers>
</logger>
and restart the server the logging configuration is reverted back by JBoss to the previous state i.e
<logger category="com.xyz.abc.aspect">
<level name="DEBUG"/>
<handlers>
<handler name="FILE"/>
</handlers>
</logger>
I have tried deleting standalone_xml_history directory and files under it , but nothing is preventing the overwriting behaviour, can any one please suggest.
I'm not 100% sure, but restarting the server probably causes a write-back action of the config. That means your config gets overwritten by with the "current" config the server knows which is the version before you edited the file.
You could simply use the management console
confguration > core > logging or use the CLI /subsystem=logging/logger=change.me.please:write-attribute(name="use-parent-handlers", value="false") to make those changes.
Alternatively change the config file when the server is stopped.
You need to update standalone.initial.xml in standalone_xml_history directory. Then restart Jboss, your changes would take place.
reference- https://docs.jboss.org/author/display/AS7/Configuration%20file%20history.html
We have Wildfly running on Domain mode in our production system. There are around 10 web servers and there is only on log file for all 10 servers. The log file is located under /var/log/wildfly/wildfly.log file. The last time I checked, the files was around 5 GB. My problems are:
Is there any way to separate the server logs so that each server has its own log file?
Is there any way to set the log file to max size limit to prevent over-growing?
Is there any way to delete the log file and start over? Logs before 2 days is useless for me so most of the data in the log file is redundant.
Regard
For (1) I'm not sure - is this OS installed? I don't have that file but I just extract the tarball.
For (2) and (3) I think it's a case of looking in domain/configuration/domain.xml or standalone/configuration/standalone.xml for the appropriate ("default"?) periodic-rotating-file-handler and adding, say:
<rotate-size value="20k"/> <!-- Limit on size of file -->
<max-backup-index value="1"/> <!-- Number of log files to keep -->
create size-rotating-file-handler
<size-rotating-file-handler name="FILE_SIZE">
<level name="DEBUG"/>
<file relative-to="jboss.server.log.dir" path="server.log"/>
<rotate-size value="1m"/> <!-- the size, could be 100k, 10m etc-->
<max-backup-index value="5"/> <!-- backup index, default is 1, please set it to a large number -->
<append value="true"/>
</size-rotating-file-handler>
use the handler created
<root-logger>
<level name="INFO"/>
<handlers>
<handler name="CONSOLE"/>
<handler name="FILE"/>
<handler name="FILE_SIZE"/> <!-- this is what you need to add -->
</handlers>
</root-logger>
Suddenly (after working fine for some time), WildFly 9.0.1 (and also 9.0.2) seem to have somehow lost the CONSOLE handler for logging.
When trying to debug an application from NetBeans 8.0.2, the Console window shows:
ERROR [stderr] (default task-14) Handler java.util.logging.ConsoleHandler is not defined
as last entry, and the web application seems to be stuck (before actually starting).
In WildFly's management console, there seems to be a root logger using 2 handlers: CONSOLE and FILE.
Both Handlers seem to be existing in standalone-full.xml:
...
<subsystem xmlns="urn:jboss:domain:logging:3.0">
<console-handler name="CONSOLE">
<level name="INFO"/>
<formatter>
<named-formatter name="COLOR-PATTERN"/>
</formatter>
</console-handler>
<periodic-rotating-file-handler name="FILE" autoflush="true">
<formatter>
<named-formatter name="PATTERN"/>
</formatter>
<file relative-to="jboss.server.log.dir" path="server.log"/>
<suffix value=".yyyy-MM-dd"/>
<append value="true"/>
</periodic-rotating-file-handler>
...
<root-logger>
<level name="INFO"/>
<handlers>
<handler name="CONSOLE"/>
<handler name="FILE"/>
</handlers>
</root-logger>
...
</subsystem>
...
When changing config in the management console, I can delete the handlers out of the root logger. Then I can save, but taking them in again seems impossible, since I get the WFLYCTL0158, telling that the handler would not be defined.
JBoss Knowledge base says you should ensure right jars (logback-classic-1.1.9.jar and logback-core-1.1.9.jar in that case) are in WEB-INF/lib directory if you are using an application framework.
UPDATE
For those who do not have access to link above, and wonder what the next steps are, you can add following to pom.xml to make it work with your application framework, which will then add it to WEB-INF/lib during the build.
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.2.3</version>
</dependency>
I'm trying to use log4j to send emailable reports that contain the logging statements from a background process. I want one email sent for each process run, not one email for each logging statement. I've looked at the SMTPAppender, but don't see a way to manually send the report when the process completes. I believe the TriggeringEventEvaluator may be the key, but one issue I'm running into is how to get a handle to the TriggeringEventEvaluator instance. I'm stuck using log4j 1.2.14 and the SMTPAppender.getEvaluator() method was introduced in 1.2.15. Any thoughts? Am I even on the right track? Does the SMTPAppender.close() method come into play here?
I want to be able to do this:
log.info(message1);
log.info(message2);
log.info(message3);
log.sendMail();
After thinking about this some more, I think I need to clarify what I'm hoping to accomplish. I'm trying to capture the logging from running a quartz job and send the resulting log as an email. The quartz job makes a bunch of service method calls into various services. I want the to include any logging those service methods perform as well as the logging of the quartz jobs itself. I was thinking I could do something like the following for capturing all the logging, but it isn't working.
// at the beginning of quartz job
Logger logger = Logger.getRootLogger();
StringWriter sw = new StringWriter();
WriterAppender wa = new WriterAppender(new SimpleLayout(), sw);
logger.addAppender(wa);
// at the end of the quartz job
String report = sw.toString();
You shouldn't use any of log4j's methods, you should configure it properly instead.
First of all, define in your log4j.properties file your appender properly:
#CONFIGURE SMTP
log4j.appender.email=org.apache.log4j.net.SMTPAppender
log4j.appender.email.SMTPHost=mail.mydomain.com
log4j.appender.email.SMTPUsername=myuser#mydomain.com
log4j.appender.email.SMTPPassword=mypw
log4j.appender.email.From=myuser#mydomain.com
log4j.appender.email.To=myuser#mydomain.com
log4j.appender.email.Subject=Log of messages
log4j.appender.email.BufferSize=1
log4j.appender.email.EvaluatorClass=TriggerLogEvent
log4j.appender.email.layout=org.apache.log4j.PatternLayout
log4j.appender.email.layout.ConversionPattern=%m
Note: code taken from this post. More information can be obtained in SMTPAppender API.
Next, make a special class that will be used just for sending email. Example:
package com.foo.mailer;
import org.apache.log4j.Logger;
public class Mailer {
private static final Logger logger = Logger.getLogger(Mailer.class);
public void logMail(String mailString) {
logger.info(mailString);
}
}
Next, put in log4j.properties configuration for this class:
# INFO level will be logged
log4j.logger.com.foo.mailer = INFO, email
# turn off additivity
log4j.additivity.com.foo.mailer = false
Now, whenever you want to send an email using log4j, put this in your code:
new Mailer().logMail("This mail should be sent");
Disclaimer: I haven't tested any of this code.
If you are using an XML configuration file, the following should be helpful.
<appender name="ErrorEmailAppender" class="org.apache.log4j.net.SMTPAppender">
<param name="SMTPHost" value="mail.mydomain.com" />
<param name="SMTPUsername" value="myuser#mydomain.com" />
<param name="SMTPPassword" value="password" />
<param name="From" value="myuser#mydomain.com" />
<param name="To" value="myuser#mydomain.com" />
<param name="Subject" value="Log of messages" />
<param name="BufferSize" value="1" />
<param name="EvaluatorClass" value="TriggerLogEvent" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%t %m%n"/>
</layout>
</appender>
<logger name="com.foo.mailer">
<level value="INFO" />
<appender-ref ref="ErrorEmailAppender"/>
</logger>
Log4j 2.x onwards, the following configuration for log4j.xml can be used. It's pretty straightforward and can be used to send emails.
You need to edit it and enter your smtp host, username, password, port and subject.
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<SMTP>
<name>Mail1</name>
<subject>SUBJECT</subject>
<to>TO_EMAIL</to>
<from>FROM_EMAIL</from>
<smtpHost>smtp.gmail.com</smtpHost>
<smtpPort>487</smtpPort>
<ignoreExceptions>false</ignoreExceptions>
<smtpUsername>username</smtpUsername>
<smtpPassword>password</smtpPassword>
<smtpProtocol>smtps</smtpProtocol>
<HtmlLayout charset="UTF-8" locationInfo="true" />
<ThresholdFilter level="ERROR"/>
</SMTP>
</Appenders>
<Loggers>
<Root level="INFO">
<AppenderRef ref="Mail1"/>
</Root>
</Loggers>
</Configuration>
Reference: Log4j SMTP Appender