i have a simple logging program ie:
public class LoggingExample1 {
public static void main(String args[]) {
try {
LogManager lm = LogManager.getLogManager();
Logger logger;
FileHandler fh = new FileHandler("log_test.txt");
logger = Logger.getLogger("LoggingExample1");
lm.addLogger(logger);
logger.setLevel(Level.INFO);
fh.setFormatter(new SimpleFormatter());
logger.addHandler(fh);
// root logger defaults to SimpleFormatter. We don't want messages
// logged twice.
//logger.setUseParentHandlers(false);
logger.log(Level.INFO, "test 1");
logger.log(Level.INFO, "test 2");
logger.log(Level.INFO, "test 3");
fh.close();
} catch (Exception e) {
System.out.println("Exception thrown: " + e);
e.printStackTrace();
}
}
}
i get this log:
Aug 1, 2011 5:36:37 PM LoggingExample1 main
INFO: test 1
Aug 1, 2011 5:36:37 PM LoggingExample1 main
INFO: test 2
Aug 1, 2011 5:36:37 PM LoggingExample1 main
INFO: test 3
but i want to remove the messages like: LoggingExample1 main and INFO
and only keep the data that are logged by code.
what can i do???
This is because you are using a SimpleFormatter which always logs the class name, method name etc. If you don't want this information, you can write your own formatter. Here is a simple example of a formatter which just outputs the log level and the log message:
import java.util.logging.*;
class MyFormatter extends Formatter{
/* (non-Javadoc)
* #see java.util.logging.Formatter#format(java.util.logging.LogRecord)
*/
#Override
public String format(LogRecord record) {
StringBuilder sb = new StringBuilder();
sb.append(record.getLevel()).append(':');
sb.append(record.getMessage()).append('\n');
return sb.toString();
}
}
Use this formatter in your file handler:
fh.setFormatter(new MyFormatter());
This will output:
INFO:test 1
INFO:test 2
INFO:test 3
Extend your class with formatter class as below:
public class MyFormatter extends SimpleFormatter{
#Override
public synchronized String format(LogRecord record){
record.setSourceClassName(MyFormatter.class .getName());
return String.format(
" [%1$s] :%2$s\n",
record.getLevel().getName(), formatMessage(record));
}
}
Then in you main class, set console handler and filehandler format as your class format object.
In my case ,it is consoleHandler.format(new MyFormatter);
filehandler.format(new Myformatter);
Most imp thing is you have to set
logger.setUseParentHandler(false);
now you are good to go!
If I understand you correctly, you want to remove INFO and only have test 1 and so on?
If that is the case, I don't think its possible. The reason is that you need to know what type of message this is.
ERROR
WARNING
INFO
DEBUG
TRACE
You can change the level to only display WARNING and up if you want.
Here is how I do this, simplified version of SimpleFormatter
package org.nibor.git_merge_repos;
import java.util.Date;
import java.util.logging.Formatter;
import java.util.logging.LogRecord;
public class CustomLogFormatter extends Formatter {
private final Date dat = new Date();
private static final String seperator = " : ";
public synchronized String format(LogRecord record) {
dat.setTime(record.getMillis());
return dat + seperator + record.getLevel().getName() + seperator + record.getMessage() + "\n";
}
}
Related
How to have same slf4j log with JDK8 and JDK11?
My java Slf4j logger:
log.info("---> {} {}", "When", String.format(matcher.group(1).replaceAll("\\{\\S+\\}", "{%s}").replace("(\\?)", ""), invocation.getArguments()));
My trace in java 8 by JDK8:
---> When I update text {bakery.DemoPage-input_text_field} with {Jenkins T5}
My trace in java 8 by JDK11:
---> When "I update text {bakery.DemoPage-input_text_field} with {Jenkins T5}"
EDIT:
I try this but same result:
String message = MessageFormat.format("---> {0} {1}",
stepAnnotation.annotationType().getSimpleName(),
String.format(matcher.group(1).replaceAll("\\{\\S+\\}", "{%s}").replace("(\\?)", ""), invocation.getArguments())
);
log.info(message);
EDIT (if you want a more simple case):
log.info("---> {} {}", "When", String.format("I update text {%s} with {%s}", "bakery.DemoPage-input_text_field", "Jenkins T5"));
EDIT with #M. Deinum proposal but do not work
log.info("---> {} " + matcher.group(1).replaceAll("\\{\\S+\\}", "{}").replace("(\\?)", ""), stepAnnotation.annotationType().getSimpleName(), invocation.getArguments());
---> When "I update text [bakery.DemoPage-input_text_field, Jenkins T5, []] with {}"
EDIT: I try other proposal with external replace:
String mes = String.format(matcher.group(1).replaceAll("\\{\\S+\\}", "{%s}").replace("(\\?)", ""), invocation.getArguments());
log.info("---> {} {}", stepAnnotation.annotationType().getSimpleName(), mes);
---> When "I update text {bakery.DemoPage-input_text_field} with {Jenkins T5}"
the problem is not come from Slf4j but from stepAnnotation.toString() different in JDK8 and JDK11)
openjdk11 and oraclejdk11 do not respect javadoc:
/**
* Returns a string representation of this annotation. The details
* of the representation are implementation-dependent, but the following
* may be regarded as typical:
* <pre>
* #com.acme.util.Name(first=Alfred, middle=E., last=Neuman)
* </pre>
*
* #return a string representation of this annotation
*/
String toString();
Solution:
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import io.cucumber.java.en.When;
public class Sof {
private static final Logger log = LoggerFactory.getLogger(Sof.class);
#When(value = "I update text {string} with {string}(\\?)")
public static void main(String[] args) {
Object as[] = { "a", "b" };
Class c = Sof.class;
Method[] methods = c.getMethods();
Method method = null;
for (Method m : methods) {
if (m.getName().equals("main")) {
method = m;
}
}
Annotation stepAnnotation = method.getAnnotation(When.class);
Class<? extends Annotation> annotationClass = stepAnnotation.annotationType();
try {
Method valueMethods = annotationClass.getDeclaredMethod("value");
if (Modifier.isPublic(valueMethods.getModifiers())) {
log.info("---> {} " + String.format(valueMethods.invoke(stepAnnotation).toString().replaceAll("\\{\\S+\\}", "{%s}").replace("(\\?)", ""), as),
stepAnnotation.annotationType().getSimpleName());
}
} catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e1) {
e1.printStackTrace();
}
}
}
I want to send file fron one agent to an other agent using JADE on same PC.
Here some error which is occur during execution.
*** Uncaught Exception for agent a ***
ERROR: Agent a died without being properly terminated !!!
java.lang.RuntimeException: Uncompilable source code - incompatible types: java.lang.String cannot be converted to byte[]
State was 2
ERROR: Agent b died without being properly terminated !!!
State was 2
at sendmessage.A.sendMessage(A.java:36)
at sendmessage.A.setup(A.java:25)
at jade.core.Agent$ActiveLifeCycle.init(Agent.java:1490)
at jade.core.Agent.run(Agent.java:1436)
at java.lang.Thread.run(Thread.java:745)
Nov 20, 2015 4:21:34 PM jade.core.messaging.MessagingService removeLocalAliases
INFO: Removing all local alias entries for agent a
Nov 20, 2015 4:21:34 PM jade.core.messaging.MessagingService removeGlobalAliases
INFO: Removing all global alias entries for agent a
*** Uncaught Exception for agent b ***
java.lang.RuntimeException: Uncompilable source code - Erroneous sym type: sendmessage.B.MyBehaviour.receive
at sendmessage.B$MyBehaviour.action(B.java:40)
at jade.core.behaviours.Behaviour.actionWrapper(Behaviour.java:344)
at jade.core.Agent$ActiveLifeCycle.execute(Agent.java:1500)
at jade.core.Agent.run(Agent.java:1439)
at java.lang.Thread.run(Thread.java:745)
Nov 20, 2015 4:21:34 PM jade.core.messaging.MessagingService removeLocalAliases
INFO: Removing all local alias entries for agent b
Nov 20, 2015 4:21:34 PM jade.core.messaging.MessagingService removeGlobalAliases
INFO: Removing all global alias entries for agent b
Nov 20, 2015 4:21:42 PM jade.core.messaging.MessagingService removeLocalAliases
INFO: Removing all local alias entries for agent rma
Nov 20, 2015 4:21:42 PM jade.core.messaging.MessagingService removeGlobalAliases
INFO: Removing all global alias entries for agent rma
Sender:Who send file to another agent via using JADE.
package sendmessage;
import jade.core.AID;
import jade.core.Agent;
import jade.core.behaviours.Behaviour;
import jade.lang.acl.ACLMessage;
import jade.lang.acl.MessageTemplate;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
/**
*
* #author Administrator
*/
public class A extends Agent {
protected void setup() {
sendMessage();
this.addBehaviour(new MyBehaviour(this));
}
private void sendMessage() {
AID r = new AID("b", AID.ISLOCALNAME);
// ACLMessage acl = new ACLMessage(ACLMessage.REQUEST);
// acl.addReceiver(r);
// acl.setContent("hello, my name is sender!");
// this.send(acl);
String fileName = "a.txt";// get file name
byte[] fileContent = "f://a.txt";// read file content
ACLMessage msg = new ACLMessage(ACLMessage.INFORM);
msg.addReceiver(r);
msg.setByteSequenceContent(fileContent);
msg.addUserDefinedParameter("file-name", fileName);
send(msg);
}
private static class MyBehaviour extends Behaviour {
MessageTemplate mt = MessageTemplate.MatchPerformative(ACLMessage.INFORM);
private static int finish;
public MyBehaviour(A aThis) {
}
#Override
public void action() {
ACLMessage acl = myAgent.receive(mt);
if (acl != null) {
System.out.println(myAgent.getLocalName() + " received a reply: " + acl.getContent() + "from " + acl.getSender());
finish = 1;
} else {
this.block();
}
}
#Override
public boolean done() {
return finish == 1;
}
}
}
Receiver: who receive file from send agent via using JADE
package sendmessage;
import jade.core.Agent;
import jade.core.behaviours.Behaviour;
import jade.lang.acl.ACLMessage;
import jade.lang.acl.MessageTemplate;
import java.io.File;
/**
*
* #author Administrator
*/
public class B extends Agent {
protected void setup() {
this.addBehaviour(new MyBehaviour(this));
}
private static class MyBehaviour extends Behaviour {
MessageTemplate mt = MessageTemplate.MatchPerformative(ACLMessage.REQUEST);
public MyBehaviour(B aThis) {
}
#Override
public void action() {
// ACLMessage acl = myAgent.receive(mt);
// if (acl!= null) {
// System.out.println(myAgent.getLocalName()+ " received a message: "+acl.getContent());
// ACLMessage rep = acl.createReply();
// rep.setPerformative(ACLMessage.INFORM);
// rep.setContent("ok, i received a message!");
// myAgent.send(rep);
ACLMessage msg = receive("Yes Received your file");
if (msg != null) {
String fileName = msg.getUserDefinedParameter("a.txt");
File f = "a.txt"; // create file called fileName
byte[] fileContent = msg.getByteSequenceContent();
// write fileContent to f
}
else {
this.block();
}
}
#Override
public boolean done() {
return false;
}
}
}
It is probably an idea to create an Ontology for your agent system if you are going to be exchanging files around alot. JADE offers the ability to use OntologyBean classes as representation of the Agent communication methods(which really simplifies things).
the BeanOntology class adds custom language in the form of predicates, concepts, etc. Inside these custom language descriptions you can place an object and any other information you may want to specify alongside it. It is actually quite simple if you follow the documentation provided from JADE --> tutorial here
good luck!
I wrote a separate class MyLogger with static method
static public void setup(String className, Exception e, Level level) {
System.out.println("className = " + className);
Logger logger = Logger.getLogger(className);
logger.setLevel(Level.INFO);
try {
fileTxt = new FileHandler("Logging.%u.%g.txt",1024 * 1024, 10, true );
// create a TXT formatter
formatterTxt = new SimpleFormatter();
fileTxt.setFormatter(formatterTxt);
logger.addHandler(fileTxt);
logger.log(level, e.toString(), e);
} catch (IOException | SecurityException ex) {
System.out.println("SecurityException ");
Logger logger2=Logger.getLogger(MyLogger.class.getName());
logger2.addHandler(new ConsoleHandler());
logger2.log(Level.SEVERE, null, ex);
}
}
This static method receives a string className which I put as a parameter into Logger.getLogger().
In another class I call MyLogger.setup(CommonFrame.class.getName(), e, Level.SEVERE).
Everything works. But the problem is that in the file I get "May 25, 2014 2:05:30 PM javagui.MyLogger setup" and I thought that it should be instead like this "May 25, 2014 2:05:30 PM javagui.CommonFrame" because I assigned that name to the logger.
Am I right? If yes, how can I fix it?
You have use the format property of the java.util.logging.SimpleFormatter to use the logger name instead of the source classname.
Modify your launch script to set the following system property:
-Djava.util.logging.SimpleFormatter.format="%1$tc %3$s%n%4$s: %5$s%6$s%n"
Or modify your logging.properties to include:
java.util.logging.SimpleFormatter.format=%1$tc %3$s%n%4$s: %5$s%6$s%n
Otherwise, you can create a custom formatter and use that extract the information you want to see in the log file.
You can use the log(LogRecord) method and specify the class name.
static public void setup(String className, Exception e, Level level) {
[...]
try {
[...]
logger.addHandler(fileTxt);
LogRecord record = new LogRecord(level, e.toString());
record.setThrown(e);
record.setSourceClassName(className);
record.setSourceMethodName("");
logger.log(record);
} catch (IOException | SecurityException ex) {
[...]
}
}
How do I print the entire stack trace using java.util.Logger? (without annoying Netbeans).
The question should've originally specified staying within Java SE. Omitting that requirment was an error on my part.
-do-compile:
[mkdir] Created dir: /home/thufir/NetBeansProjects/rainmaker/build/empty
[mkdir] Created dir: /home/thufir/NetBeansProjects/rainmaker/build/generated-sources/ap-source-output
[javac] Compiling 13 source files to /home/thufir/NetBeansProjects/rainmaker/build/classes
[javac] /home/thufir/NetBeansProjects/rainmaker/src/model/TelnetEventProcessor.java:44: error: 'void' type not allowed here
[javac] log.severe(npe.printStackTrace(System.out));
[javac] ^
[javac] 1 error
BUILD FAILED
code with the error:
package model;
import java.util.Observable;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class TelnetEventProcessor extends Observable {
private static Logger log = Logger.getLogger(TelnetEventProcessor.class.getName());
private String string = null;
public TelnetEventProcessor() {
}
private void stripAnsiColors() {
Pattern regex = Pattern.compile("\\e\\[[0-9;]*m");
Matcher regexMatcher = regex.matcher(string);
string = regexMatcher.replaceAll(""); // *3 ??
}
public void parse(String string) {
this.string = string;
ifs();
}
// [\w]+(?=\.)
private void ifs() {
log.fine("checking..");
if (string.contains("confusing the hell out of")) {
Pattern pattern = Pattern.compile("[\\w]+(?=\\.)"); //(\w+)\.
Matcher matcher = pattern.matcher(string);
String enemy = null;
GameData data = null;
while (matcher.find()) {
enemy = matcher.group();
}
try {
data = new GameData.Builder().enemy(enemy).build();
log.fine("new data object\t\t" + data.getEnemy());
setChanged();
notifyObservers(data);
} catch (NullPointerException npe) {
log.severe(npe.printStackTrace(System.out));
}
} else if (string.contains("Enter 3-letter city code:")) {
log.fine("found enter city code");
} else {
}
}
}
see also:
https://stackoverflow.com/a/7100975/262852
The severe method is only used to log severe messages without associated throwable information. If you need to log throwable information then you should use the log method instead:
try {
data = new GameData.Builder().enemy(enemy).build();
log.fine("new data object\t\t" + data.getEnemy());
setChanged();
notifyObservers(data);
} catch (NullPointerException npe) {
log.log(Level.SEVERE, npe.getMessage(), npe);
}
Why don't you put the exception in the logger?
You can use this method :
logger.log(Level level, String msg, Throwable thrown)
Maybe a duplicated question? Java - Need a logging package that will log the stacktrace
Below the explanation from the given url
Using log4j
this is done with:
logger.error("An error occurred", exception);
The first argument is a message to be displayed, the second is the
exception (throwable) whose stacktrace is logged.
Another option is commons-logging,
where it's the same:
log.error("Message", exception);
With java.util.logging
this can be done via:
logger.log(Level.SEVERE, "Message", exception);
You don't explicitly print the stack trace; Throwables have stack traces attached to them, and you can pass a Throwable to the log methods:
log(Level level, String msg, Throwable thrown)
You could use Apache ExceptionUtils. In your case
try {
data = new GameData.Builder().enemy(enemy).build();
log.fine("new data object\t\t" + data.getEnemy());
setChanged();
notifyObservers(data);
} catch (NullPointerException npe) {
logger.info(**ExceptionUtils.getFullStackTrace(npe)**);
}
You should redirect the System.err to the logger, the process is not too simple but you can use this code:
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
public class LogOutputStream extends ByteArrayOutputStream {//java.io.OutputStream {
private String lineSeparator;
private Logger logger;
private Level level;
public LogOutputStream(Logger logger, Level level) {
super();
this.logger = logger;
this.level = level;
this.lineSeparator = System.getProperty("line.separator");
}
#Override
public void flush() throws IOException {
String record;
synchronized (this) {
super.flush();
record = this.toString();
super.reset();
if ((record.length() == 0) || record.equals(this.lineSeparator)) {
// avoid empty records
return;
}
this.logger.logp(this.level, "", "", record);
}
}
}
And The code to set this (that should called the when you first create the logger
Logger logger = Logger.getLogger("Exception");
LogOutputStream los = new LogOutputStream(logger, Level.SEVERE);
System.setErr(new PrintStream(los, true));
This will redirect the System.err stream to the logger.
You can also try to use ExceptionUtils from apache commons
The exception is due to the printstacktrace method being void, meaning it doesn't return anything. You are trying to do:
log.severe(npe.printStackTrace(System.out));
My guess is that the severe method needs a String and not void.
I have developed a spring application, I want to configure it with apache log4j, have downloaded it and put the jar in project's class path. Below is my log4j.Properties file.
# Root logger option
log4j.rootLogger=INFO, file
# Direct log messages to a log file
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.File=C\:\\loging.log
log4j.appender.file.MaxFileSize=1MB
log4j.appender.file.MaxBackupIndex=1
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
And below is my main spring application class.
import org.apache.log4j.Logger;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.FileSystemResource;
public class DrawingClass {
public static void main(String args[])
{
//without dependency injection
/*Triangle t1 = new Triangle();
t1.draw();*/
//with dependency injection
BeanFactory factory = new XmlBeanFactory(new FileSystemResource("Spring.xml"));
Triangle t1 =(Triangle) factory.getBean("triangle");
t1.draw();
}
}
Please advise if I want to put the log.info in my above main class what modifications I need to do in my main class and also please advise what modifications I need to done to call log4j in my main class?
come up with this solution and it works ..the edited log4j.properties file is
### direct messages to file or.log ###
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=C:/logs/s.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1} - %m%n
log4j.appender.file.append=true
### set log levels - for more verbose logging change 'info' to 'debug' ##
log4j.rootCategory=ALL, file
log4j.logger.Demo=\=debug
log4j.logger.org.eclipse=debug
and the way to callit from main class is
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.FileSystemResource;
public class DrawingClass {
/* Get actual class name to be printed on */
static final Logger log = Logger.getLogger(DrawingClass.class);
public static void main(String args[])
{PropertyConfigurator.configure("log4j.properties");
//without dependency injection
/*Triangle t1 = new Triangle();
t1.draw();*/
log.info("Before execution");
//with dependency injection
BeanFactory factory = new XmlBeanFactory(new FileSystemResource("Spring.xml"));
Triangle t1 =(Triangle) factory.getBean("triangle");
log.info("Hello this is an info message");
t1.draw();
log.info("after object execution");
}
}
If there is any other better way then please advise .
Can you try adding this line to your class -
public class DrawingClass {
static final Logger log = Logger.getLogger(DrawingClass.class);
public static void main(String args[])
{
//without dependency injection
/*Triangle t1 = new Triangle();
t1.draw();*/
log.info("Before execution");
//with dependency injection
BeanFactory factory = new XmlBeanFactory(new FileSystemResource("Spring.xml"));
Triangle t1 =(Triangle) factory.getBean("triangle");
t1.draw();
}
}
Now let me know if anything gets added to the log.
This link might help you - http://www.dzone.com/tutorials/java/log4j/sample-log4j-properties-file-configuration-1.html
For using logging in my project I made such things:
1) Defined special annotation that should mark fields where logger should be injected:
#Retention(RUNTIME)
#Target(FIELD)
#Documented
public #interface InjectLogger {
}
2) Then created special BeanPostProcessor for injected logger into annotated field:
#Component(value="loggerInjector")
public class LoggerInjector implements BeanPostProcessor {
#Override
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
return bean;
}
#Override
public Object postProcessBeforeInitialization(final Object bean, String beanName)
throws BeansException {
ReflectionUtils.doWithFields(bean.getClass(), new FieldCallback() {
public void doWith(Field field) throws IllegalArgumentException,
IllegalAccessException {
// make the field accessible if defined private
ReflectionUtils.makeAccessible(field);
if (field.getAnnotation(InjectLogger.class) != null) {
Logger log = LoggerFactory.getLogger(bean.getClass());
field.set(bean, log);
}
}
});
return bean;
}
}
3) After this in necessary bean mark property where logger should be injected by #InjectLogger annotation and use this logger in your code.
#InjectLogger
private Logger logger;
public void doSomething(...) {
try{
...
} catch (Exception e) {
logger.error("bla bla bla", e);
}
}
In my project I use slf4j with log4j as concrete implementation. But with log4j it will be similar.
Also you need to know that by default all Spring libs using common-logging. And if you want that Spring libs write their log to your file you should use special additionla lib. You can get them, as I remember, from appache site. For slf4j such lib is named jcl-over-slf4j-1.6.4.jar.
EDIT 2:
Also in spring the good practise is to use AOP for logging. Here is an example of simplified Aspect:
#Component
#Aspect
#Order(value=2)
public class LoggingAspect {
#Around("execution(* com.blablabla.server..*.*(..))")
public Object logMethod(ProceedingJoinPoint joinPoint) throws Throwable{
final Logger logger = LoggerFactory.getLogger(joinPoint.getTarget().getClass().getName());
Object retVal = null;
try {
StringBuffer startMessageStringBuffer = new StringBuffer();
startMessageStringBuffer.append("Start method ");
startMessageStringBuffer.append(joinPoint.getSignature().getName());
startMessageStringBuffer.append("(");
Object[] args = joinPoint.getArgs();
for (int i = 0; i < args.length; i++) {
startMessageStringBuffer.append(args[i]).append(",");
}
if (args.length > 0) {
startMessageStringBuffer.deleteCharAt(startMessageStringBuffer.length() - 1);
}
startMessageStringBuffer.append(")");
logger.trace(startMessageStringBuffer.toString());
StopWatch stopWatch = new StopWatch();
stopWatch.start();
retVal = joinPoint.proceed();
stopWatch.stop();
StringBuffer endMessageStringBuffer = new StringBuffer();
endMessageStringBuffer.append("Finish method ");
endMessageStringBuffer.append(joinPoint.getSignature().getName());
endMessageStringBuffer.append("(..); execution time: ");
endMessageStringBuffer.append(stopWatch.getTotalTimeMillis());
endMessageStringBuffer.append(" ms;");
logger.trace(endMessageStringBuffer.toString());
} catch (Throwable ex) {
StringBuffer errorMessageStringBuffer = new StringBuffer();
// Create error message
logger.error(errorMessageStringBuffer.toString(), e)
throw ex;
}
return retVal;
}
}
# LOG4J configuration
log4j.rootLogger= DEBUG, INFO, Appender1, Appender2
log4j.appender.Appender1=org.apache.log4j.ConsoleAppender
log4j.appender.Appender1.layout=org.apache.log4j.PatternLayout
log4j.appender.Appender1.layout.ConversionPattern=%-7p %d [%t] %c %x - %m%n
log4j.appender.Appender2=org.apache.log4j.FileAppender
log4j.appender.Appender2.File=D:/Project Log/Demo/demo.log
log4j.appender.Appender2.layout=org.apache.log4j.PatternLayout
log4j.appender.Appender2.layout.ConversionPattern=%-7p %d [%t] %c %x - %m%n
Write this code in log4j.properties which is in Resources folder of src folder.
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
Write this above code in porm.xml file or download jar for this dependency.
<context:property-placeholder location="classpath:log4j.properties" />
write this above code between and in your spring-config.xml
package com.apmc.controller;
import org.apache.log4j.Logger;
import java.text.DateFormat;
import java.util.Date;
import com.apmc.Generic.RandomGenerator;//This my own made class So You need to create //RandomGenerator for use it
#Controller
public class StateController {
private static Logger logger = Logger.getLogger(StateController.class);
DateFormat df = new SimpleDateFormat("ddMMyyHHmmss");
Date dateobj = new Date();
int randNum = RandomGenerator.randInt(1000, 9999);
String successMsg = "", errorMsg = "";
#Autowired
StateService stateService;
List<State> newList = new ArrayList();
#RequestMapping(value = "/Admin/admin/NewState_form")
public ModelAndView stateForm(#ModelAttribute State state) {
try {
logger.info("\n stateForm Started \n errorcode : "+errorcode);
newList = stateService.loadAll();
logger.info("\n stateForm Completed");
errorMsg = "";
} catch (Exception e) {
errorcode = ""+df.format(dateobj)+randNum;
errorMsg = " New State Form Error \n Please contact Admin and errorcode:" +errorcode;
successMsg = "";
logger.error("error code for stateForm in StateController" +df.format(dateobj)+" errorcode: "+errorcode);
}
return new ModelAndView("state").addObject("editState", new State())
.addObject("errorMsg", errorMsg) .addObject("showStateList",newList)
.addObject("successMsg", successMsg);
}
}
Above example for how to use log in Controller or any Java Class
Here I made for error Tracking create error code show for commmunicate with error using RandomGenerator.java write as below given
package com.apmc.Generic;
import java.util.Random;
public class RandomGenerator {
/**
* Returns a pseudo-random number between min and max, inclusive.
* The difference between min and max can be at most
* <code>Integer.MAX_VALUE - 1</code>.
*
* #param min Minimum value
* #param max Maximum value. Must be greater than min.
* #return Integer between min and max, inclusive.
* #see java.util.Random#nextInt(int)
*/
public static int randInt(int min, int max) {
// NOTE: Usually this should be a field rather than a method
// variable so that it is not re-seeded every call.
Random rand = new Random();
// nextInt is normally exclusive of the top value,
// so add 1 to make it inclusive
int randomNum = rand.nextInt((max - min) + 1) + min;
return randomNum;
}
}