Logging errors to two appenders - java

I'm trying to configure Logback (in Grails using Groovy configuration) so that:
any errors (from anywhere) are logged to a rolling file and send an email
all debug output from my classes is sent to the rolling file
This is what I have so far:
appender("ROLLING", RollingFileAppender) { ... }
appender("EMAIL", SMTPAppender) { ... }
logger("my.package", DEBUG, ["ROLLING"], false)
root(ERROR, ["ROLLING", "EMAIL"])
It seems that the rolling file gets what I expect (debug from my package at least) but the EMAIL appender gets nothing.
How can I send the errors to the EMAIL appender?

Related

Using Logger in Domino Java Agent

I want to get away from using a string buffer and System.out.println in Java agents.
I want to use java.util.Logger.
When I log using
logger.info("logger started")
output in the Domino Server Console
[0FDC:000D-1258] 06/07/2018 03:13:57 PM Agent Manager: Agent error: Jun 07, 2018 3:13:57 PM TransferDocsToServerNSF NotesMain INFO: logger started.
Notice the Domino platform added "Agent error" before the output when using Level.INFO
I then tried using .logp with Level.FINE and no output shows up.
logger.setLevel(Level.ALL); or logger.setLevel(Level.FINE);
logger.logp(Level.FINE,this.getClass().getSimpleName(),"main","logger started.");
output: No output. Anything lower than Level.INFO does not print.
How can I target the Domino logging to show Level.FINE?
And, what can I do for INFO for Domino not to consider all Level.INFO to be errors?
I was able to print logging at different levels after editing this file on the server:
(server install) IBM/Domino/jvm/lib/logging.properties
# Default global logging level.
# This specifies which kinds of events are logged across
# all loggers. For any given facility this global level
# can be overriden by a facility specific level
# Note that the ConsoleHandler also has a separate level
# setting to limit messages printed to the console.
.level= FINEST
# Limit the message that are printed on the console to INFO and above.
java.util.logging.ConsoleHandler.level = FINEST
Testing Java code
logger = Logger.getLogger("com.xpagesbeast");
logger.setUseParentHandlers(false); //do not use the global logger (avoid two outputs per log)
create a custom handler if one does not exist, watch our here, you can create more than one the JVM will track.
if(logger.getHandlers().length == 0){
System.out.println("Adding a new handler");
consoleHandler = new ConsoleHandler();
logger.addHandler(consoleHandler);
}
logger.getHandlers()[0].setLevel(Level.INFO);
logger.severe("test severe logging " + logger.getName());
logger.warning("test warning logging " + logger.getName());
logger.info("test info logging " + logger.getName());
logger.finer("test finer logging " + logger.getName());
logger.finest("test finest logging " + logger.getName());
Now I can set a debug flag in a Database or environment variable and assign the logging level as detailed as I want.
For example, if I want to debug the application, I can set a value in a database that is read by the application that determines what logging level that handler will use.

Log4J SMTPAppender Java

I want to send a mail notification in a java application via log4j. However the first try with configurated log4j.properties file, worked like charm. But since I want a dynamic subject, which is generated in runtime, I tried the following commands, with no success:
final static Logger logger = Logger.getRootLogger();
...
public static mail(String msg, String subj) {
SMTPAppender mailAppend = new SMTPAppender();
mailAppend.setBufferSize(3);
mailAppend.setSMTPHost("smtphostname");
mailAppend.setTo("ex#mple.com");
mailAppend.setSubject(subj);
logger.addAppender(mailAppend);
logger.error(msg);
}
output:
log4j:ERROR Message object not configured.
So did I miss a necessary getter?
An SMTPAppender can be configured either using a xml or properties
file or manually using the setters. When you use the setters, you need
to activate the options by calling the function activateOptions or
else you would get the "ERROR Message object not configured" message.
This is to ensure that the options would only become effective when
all the related options have been set (e.g. one would not want to have
the host setting become effective before the port is set).
FROM : https://community.oracle.com/thread/1758275?start=0&tstart=0

Avoiding Multiple Logging of Same Message Due to Default behaviour in Log4j

I am working in Grails application and want to log messages in different files. I want to log exceptions, normal and API logs in different files. But according to Log4j general roles, If we set logger level to 'Info' then warn and error messages will also start logging in this file while I want to log error messages in different file. So, thus my error messages will be logged twicely in error file and in info file too. While I want that 'info' logger log just 'info' level messages not 'error' level messages too. And 'error' logger just log error messages.
Below is my Log4j Configuration:
log4j = {
def layoutPattern = new PatternLayout("[%d{ISO8601}] %m \r\n")
def dailyRollingInfoFile = new DailyRollingFileAppender(
name:"rollingInfoFileAppender",
layout: layoutPattern,
//Path of the Log File
fileName:"C:\\MS-Logs\\Application\\MSLogs.log",
datePattern: "'.'dd-MM-yyyy")
def dailyRollingExceptionFile = new DailyRollingFileAppender(
name:"rollingExceptionFileAppender",
layout: layoutPattern,
//Path of the Log File
fileName:"C:\\MS-Logs\\Exceptions\\ExceptionLogs.log",
datePattern: "'.'dd-MM-yyyy")
def dailyRollingExceptionAPIFile = new DailyRollingFileAppender(
name:"rollingAPIFileAppender",
layout: layoutPattern,
//Path of the Log File
fileName:"C:\\MS-Logs\\API\\MS-NotificationsLogs.log",
datePattern: "'.'dd-MM-yyyy")
//For logging exceptions stack trace
appenders {
appender dailyRollingInfoFile
appender dailyRollingExceptionFile
appender dailyRollingExceptionAPIFile
}
root {
info 'rollingInfoFileAppender', additivity: false
debug 'rollingAPIFileAppender', additivity: false
error 'rollingExceptionFileAppender'
}
}
And Now, this is how I add filters:
dailyRollingExceptionFile.addFilter(new org.apache.log4j.varia.LevelMatchFilter(levelToMatch:'ERROR', acceptOnMatch: true))
dailyRollingExceptionFile.addFilter(new org.apache.log4j.varia.DenyAllFilter())
//To make it sure that It will just Log, Messages by Info Logger
dailyRollingInfoFile.addFilter(new org.apache.log4j.varia.LevelMatchFilter(levelToMatch:'INFO', acceptOnMatch: true))
dailyRollingInfoFile.addFilter(new org.apache.log4j.varia.DenyAllFilter())
//To make it sure that It will just Log, Messages by API Logger
dailyRollingAPIFile.addFilter(new org.apache.log4j.varia.LevelMatchFilter(levelToMatch:'DEBUG', acceptOnMatch: true))
dailyRollingAPIFile.addFilter(new org.apache.log4j.varia.DenyAllFilter())
How, It may be possible to avoid same message being logged twicely in different files ? How can we log messages in different files without being repeating it in other file ?
Thanks for your Time :)
I believe Log4j's LevelMatchFilter allows you to do what you're after:
def dailyRollingInfoFile = new DailyRollingFileAppender(...)
dailyRollingInfoFile.addFilter(new org.apache.log4j.varia.LevelMatchFilter(levelToMatch:'INFO', acceptOnMatch: true))
dailyRollingInfoFile.addFilter(new org.apache.log4j.varia.DenyAllFilter())
The DenyAllFilter drops the messages that the LevelMatchFilter does not match (ie. everything other than level INFO)

Log4J SMTP digest/aggregate emails?

I have a JBOSS batch application that sometimes sends hundreds on emails in a minute to the same email address with Log4J errors. This causes problems with Gmail, because it says we are sending emails too quickly for that gmail account.
So I was wondering if there was a way to basically create a "digest" or "aggregate" email puts all the error logs in 1 email and sends that every 5 minutes. So that way every 5 minutes we may get a large email, but at least we actually get the email instead of it being delayed for hours and hours by gmail servers rejecting it.
I read this post that suggested something about using an evaluator to do that, but I couldn't see how that is configured in the Log4J xml configuration file. It also seemed like it might not be able to "digest" all the logs into 1 email anyway.
Has anyone done this before? Or know if it's possible?
From (the archived) SMTPAppender Usage page:
set this property
log4j.appender.myMail.evaluatorClass = com.mydomain.example.MyEvaluator
Now you have to create the evaluator class and implement the org.apache.log4j.spi.TriggeringEventEvaluator interface and place this class in a path where log4j can access it.
//Example TriggeringEventEvaluator impl
package com.mydomain.example;
import org.apache.log4j.spi.LoggingEvent;
import org.apache.log4j.spi.TriggeringEventEvaluator;
public class MyEvaluator implements TriggeringEventEvaluator {
public boolean isTriggeringEvent(LoggingEvent event) {
return true;
}
}
You have to write the evaluator logic within this method.
I created a free useable solution for log4j2 with an ExtendedSmtpAppender.
(If you still use log4j 1.x, simply replace your log4j-1.x.jar with log4j-1.2-api-2.x.jar - and log4j-core-2.x.jar + log4j-api-2.x.jar of course.)
You get it from Maven Central as de.it-tw:log4j2-extras (This requires Java 7+ and log4j 2.8+).
If you are restricted to Java 6 (and thus log4j 2.3) then use de.it-tw:log4j2-Java6-extras
Additionally, see the GitLab project: https://gitlab.com/thiesw/log4j2-extras (or https://gitlab.com/thiesw/log4j2-Java6-extras)
[OLD text:
If you use log4j2, see answer to other stack overflow issue: https://stackoverflow.com/a/34072704/5074004
Or directly go to my external but publically available solution presented in https://issues.apache.org/jira/browse/LOG4J2-1192
]

Is it possible to log only one level messages with Log4J

If I set the log level to DEBUG, All messages with log level >= DEBUG will be logged/printed.
But can I set log level to only DEBUG, such that messages with log level only with DEBUG will be printed. Or can give a range like print all messages whose log level is >=DEBUG but < ERROR?
Maybe you can use a LevelMatchFilter?
At some situation, You have to write logs to different outputs according to the level. how can it be done by simply configuration of Log4j? There are some methods below.
http://wiki.apache.org/logging-log4j/LogToAppenderByLevel
As said Jarle you have to use LevelMatchFilter.
I will demonstrate it with one simple exam:
log4j.rootLogger = WARN, admin
log4j.appender.admin=org.apache.log4j.rolling.RollingFileAppender
log4j.appender.admin.rollingPolicy = org.apache.log4j.rolling.TimeBasedRollingPolicy
log4j.appender.admin.rollingPolicy.FileNamePattern = Files\\TestLevels-%d{dd-MM-yyy}.txt
log4j.appender.admin.layout = org.apache.log4j.PatternLayout
log4j.appender.admin.layout.ConversionPattern = Date: %d{dd-MM-yyyy} Time: %d{HH:mm:ss} Message [%m]%n
log4j.appender.admin.filter.01=org.apache.log4j.varia.LevelMatchFilter
log4j.appender.admin.filter.01.LevelToMatch=FATAL
log4j.appender.admin.filter.01.AcceptOnMatch=false
log4j.appender.admin.filter.02=org.apache.log4j.varia.LevelMatchFilter
log4j.appender.admin.filter.02.LevelToMatch=ERROR
log4j.appender.admin.filter.02.AcceptOnMatch=true
log4j.appender.admin.filter.03=org.apache.log4j.varia.LevelMatchFilter
log4j.appender.admin.filter.03.LevelToMatch=WARN
log4j.appender.admin.filter.03.AcceptOnMatch=false
In my source I append only ERROR messages to file with name TestLevels.txt

Categories

Resources