It's been a while that I began with log4j; pretty cool logging framework. I've done other type of logging like Console and File Logging. So trying for DB Adapters with mysql for Database logging. Accordingly, I've created following property file named log4j.properties as -
# Define the root logger with appender file
log4j.rootLogger = DEBUG, DB
# Define the DB appender
log4j.appender.DB=org.apache.log4j.jdbc.JDBCAppender
# Set JDBC URL
log4j.appender.DB.URL=jdbc:mysql://localhost:3306/test
# Set Database Driver
log4j.appender.DB.driver=com.mysql.jdbc.Driver
# Set database user name and password
log4j.appender.DB.user=root
log4j.appender.DB.password=
# Set the SQL statement to be executed.
log4j.appender.DB.sql=insert into log(date,level,message) values("%d","%p","%m")
# Define the layout for file appender
log4j.appender.DB.layout=org.apache.log4j.PatternLayout
And used it in a test class in following way -
public class DBLoggerTest {
static Logger logger;
public DBLoggerTest() {
//System.setProperty("log4j.configuration", "log4j.properties");
logger = Logger.getLogger(DBLoggerTest.class.getName());
}
public static void main(String[] args) {
new DBLoggerTest();
logger.info("This is a test info");
logger.error("This is an error messsage");
}
}
But I got following error -
log4j:WARN No appenders could be found for logger (com.satyam.logger.test.DBLoggerTest).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
Any help please...?
If you are using mysql. create a file log4j.properties. This worked for me.
Put this at the root folder of you application. i.e root of all packages. I also do have a table logs with fields id,date,user, message and class.
log4j.rootLogger=DEBUG,DB
log4j.appender.DB=org.apache.log4j.jdbc.JDBCAppender
log4j.appender.DB.URL=jdbc:mysql://localhost:3306/test
log4j.appender.DB.user=root
log4j.appender.DB.password=root
log4j.appender.DB.sql=INSERT INTO logs(date, user, message,class) VALUES ('%d{yyyy-MM-dd HH:mm:ss}', '%X{User}','%m','%c')
log4j.appender.DB.layout=org.apache.log4j.PatternLayout
log4j.appender.CA.layout.ConversionPattern=INSERT INTO logs (date, user,message,class) VALUES ('%d{yyyy-MM-dd HH:mm:ss}', '%X{User}','%m','%c')
log4j.category.ke.co=ERROR
log4j.category.ke.co.appender-ref=DB
Then use it as follows.
package com.zeddarn;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import org.apache.log4j.Logger;
import org.apache.log4j.MDC;
public class MySQLDatabaseConnector {
static ThreadLocal<Connection> connection = new ThreadLocal<Connection>();
private static Logger logger = Logger.getLogger(MySQLDatabaseConnector.class);
public static Connection getDBConnection() {
//check if a mysql connection already exits. This is to avoid reconnecting
if (connection.get() == null) {
try {
//loading the mysql driver. This means you also have to add mysql libary. You can add manually or via maven
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
//do something to deal with the error of missing mysql driver e.g notification to the user.
MDC.put("User", "loggeduser");
logger.error(e.getMessage());
MDC.getContext().clear();
}
try {
connection.set(DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "root"));
} catch (SQLException e) {
MDC.put("User", "loggeduser");
logger.error(e.getMessage());
MDC.getContext().clear();
}
}
return connection.get();
}
public static void main(String args[]) {
MDC.put("User", "loggeduser");
logger.error("message from exception.getMessage() method");
MDC.getContext().clear();
}
}
Related
I have been using Tomcat,JBoss,Glassfish etc for years.
In these containers I have used Log4j, JDK Logging etc. It is very easy.
I am struggling to get any logging from my application in Weblogic 12c.
The logs get written to stderr and not to a log file.
private final static Logger log = Logger.getLogger(TestingService.class.getName());
log.log(Level.SEVERE,"My log " + text);
In the Admin console
Logging implementation: JDK
Severity level: INFO
The behaviour is the same if I configure Log4J by following the log4j Weblogic config process.
You can try some codes like the following to get the Weblogic domain logger and server logger in your application:
import java.util.logging.Logger;
import weblogic.logging.LoggerNotAvailableException;
import weblogic.logging.LoggingHelper;
public class GetLogger {
public static Logger getLogger(){
Logger logger = null ;
try {
logger = LoggingHelper.getDomainLogger() ;
} catch (LoggerNotAvailableException e) {
logger = LoggingHelper.getServerLogger() ;
}
return logger ;
}
}
I've made an application and exported it as jar file.
If the jar-application crashes for some reason I want it to generate a crash-log text file with the error.
If I run the application in Eclipse, then eclipse always tells me where it crashed, can I get the same kind of message in a text-file instead when running the application as a jar?
I run my jar-file by typing this:
java -jar MyApplication.jar
Can I add something to this command in order to generate a crash-log if a crash occurs?
Thanks!
I used this solution in the end, which works exactly like I want it to.
Everytime the application crashes it saves the exception in a text file in a subfolder named "crashlogs" with the date and time as filename.
Just added this code at the start of my main function
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
#Override
public void uncaughtException(Thread t, Throwable e) {
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");
String filename = "crashlogs/"+sdf.format(cal.getTime())+".txt";
PrintStream writer;
try {
writer = new PrintStream(filename, "UTF-8");
writer.println(e.getClass() + ": " + e.getMessage());
for (int i = 0; i < e.getStackTrace().length; i++) {
writer.println(e.getStackTrace()[i].toString());
}
} catch (FileNotFoundException | UnsupportedEncodingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
});
you can use logging framework like log4j
simple example
Java
import org.apache.log4j.Logger;
import java.io.*;
import java.sql.SQLException;
import java.util.*;
public class log4jExample{
/* Get actual class name to be printed on */
static Logger log = Logger.getLogger(
log4jExample.class.getName());
public static void main(String[] args)
throws IOException,SQLException{
log.debug("Hello this is an debug message");
log.info("Hello this is an info message");
}
}
log4j.properties
# Define the root logger with appender file
log = /usr/home/log4j
log4j.rootLogger = DEBUG, FILE
# Define the file appender
log4j.appender.FILE=org.apache.log4j.FileAppender
log4j.appender.FILE.File=${log}/log.out
# Define the layout for file appender
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.conversionPattern=%m%n
If you want to do it without loging
Is there any way to specify Log4J 2.x log4j2.xml file location manually (like DOMConfigurator in Log4J 1.x), without messing with classpath and system properties?
You could use the static method #initialize(String contextName, ClassLoader loader, String configLocation) (see source here) in org.apache.logging.log4j.core.config.Configurator.
(You can pass null for the class loader.)
Be aware that this class is not part of the public API so your code may break with any minor release.
For completeness, you can also specify the location of the configuration file with this system property:
-Dlog4j.configurationFile=path/to/log4j2.xml
If you are using log4j2 and properties are in defined in log4j2.properties file then use this.
-Dlog4j2.configurationFile=file:/home/atul/log4j2.properties
For log4j version 2.12.1, you can find how to reconfigure log4j2 here.
Below is an example
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.LoggerContext;
File file = new File("C:\\Path for Windows OS\\yourConfig.xml");
LoggerContext context = (LoggerContext) LogManager.getContext(false);
context.setConfigLocation(file.toURI());
Logger log = LogManager.getLogger(YourClass.class);
It seems to me that way of configuring log4j2 is changing with new releases, so you should be aware of that.
In Windows, be aware that you need to use a URI with the log4j.configurationFile property
-Dlog4j.configurationFile=file://C:\path\to\log4j2.xml
Using the LoggerContext allows to setConfigLocation.
File f = new File(this.logConfigFile);
URI fc = f.toURI();
System.out.println("Loading logging config file: " + fc);
Logger l = (Logger) LogManager.getLogger(LogManager.ROOT_LOGGER_NAME);
l.getContext().setConfigLocation(fc);
or alternatively
LoggerContext.getContext().setConfigLocation(java.net.URI);
You can initialize like below as well
ConfigurationSource source = new ConfigurationSource(new FileInputStream(log4j file Path));
XmlConfiguration xmlConfig = new XmlConfiguration(source);
Logger logger = (Logger) LogManager.getLogger();
logger.getContext().start(xmlConfig);
In each class you can get logger instance as below
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
private final Logger logger = LogManager.getLogger(ABC.class);
Step: 1 - Get ready with your log4J.xml file with the appender details (Mostly under the resource folder)
Step: 2 - Following code should be added to the configuration class (In the previous log4J we had PropertyConfigurator and now we need to go with LoggerContext)
String log4JFilePath = "file path of your log4J.xml file";
LoggerContext loggerContext = (LoggerContext)LoggerManager.getContext(false);
File file = new File(log4JFilePath);
loggerContext.setConfigLocation(file.toURI());
Step: 3 - Add the following line to utilise the logger in any classes
private static final Logger logger = LogManager.getLogger(yourClassName.class);
logger.info("log here");
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.config.Configurator;
public class Foo {
public static void main(String[] args) {
Configurator.initialize(null, "src/main/config/log4j2.xml"); //path specify
Logger logger = LogManager.getLogger(APITestToolMain.class);
logger.info("working");
}
}
resource: https://www.baeldung.com/spring-boot-change-log4j2-location
void initializeLogger()
{
try
{
String basepath=checkpath();
File f = new File(basepath+"\\config\\log4j2.properties");
URI fc = f.toURI();
LoggerContext context = (LoggerContext) LogManager.getContext(false);
context.setConfigLocation(f.toURI());
}
catch (Exception e)
{
errorlog="Unable to load logging property:";
System.out.println(errorlog+": "+e.getMessage());
}
}
This is the way I initialize my log4j2 properties file from a different location, so what I simply do is to call the initializeLogger() method in my main method.
And it works perfectly.
Perhaps you need to see what the checkpath() blocks looks like, I added the function below.
String checkpath()
{
String parentpath="";
try
{
URL url=getClass().getProtectionDomain().getCodeSource().getLocation();
File f=new File(url.toURI());
parentpath=f.getParent();
}
catch(Exception ex)
{
//logger.error("unable to retrieve application parent path");
}
return parentpath;
}
I am trying to retrieve data installed on the database server JAVA DB located in jdk1.7.0_06. I am able to make connection to the server and create the database. But i am getting following error for the compilation and running:
No suitable driver found for jdbc:derby:AddressBook
Please can you help me! Thank you
I stated, "I wonder if you need to set the derby.system.home property as the Java DB tutorials suggest. Have you tried this? Something like, System.setProperty("derby.system.home", DERBY_HOME_PATH); where the second parameter is the path to your database's home directory."
And you replied:
#HovercraftFullOfEels, i think i didn't but i am sure that i have set some envariable variables via command line.
#Dorji: that doesn't set the System properties in your JVM though. I still think that you need to set this property before using your database. For example,
public class Test {
public static final String DERBY_HOME = "derby.system.home";
// ***** the two Strings below will be different for you *****
public static final String DERBY_HOME_PATH = "D:/DerbyDB";
private static final String DB_NAME = "sample";
public static void main(String[] args) {
System.setProperty(DERBY_HOME, DERBY_HOME_PATH);
Connection conn = null;
try {
Class.forName("org.apache.derby.jdbc.EmbeddedDriver").newInstance();
conn = DriverManager.getConnection("jdbc:derby:" + DB_NAME);
} catch (InstantiationException | IllegalAccessException
| ClassNotFoundException | SQLException e) {
e.printStackTrace();
} finally {
if (conn == null) {
System.exit(-1);
}
}
// .... etc...
My derby.system.home directory is D/:DerbyDB, and my database resides in the D/:DerbyDB/sample directory:
This of course will be different for you.
I have one query is that if I write a simple Java class and I want to see the logs that are executed at the behind, such that are executed at the backend by the JVM. I have log4j JAR with me. Could you please give me advice to how to achieve this?
I would to see the same logs that are generated in case of a WebApp, so I can reuse it for a Java App.
try looking at log4j api/demo here http://www.vaannila.com/log4j/log4j-tutorial/log4j-tutorial.html
you can generate log for any class and any application afaik using log4j , which needs not necessarily be a web app
Here is a very simple example that you should be able to adapt to what you are trying to achieve.
Step 1:Import log4j jar file in your project
Step 2:-Create a Log java file
public Log(Class className) {
logger = Logger.getLogger(className.getClass());
logger.getClass();
final String LOG_PROPERTIES_FILE_NAME = "log4j.properties";
props = loadLogFile(LOG_PROPERTIES_FILE_NAME, className);
//props =getPropsFile(LOG_PROPERTIES_FILE_NAME, className);
PropertyConfigurator.configure(props);
}
public static Properties loadLogFile(String propertyFile, Class className) {
//String filePath="";
try {
Properties ps = null;
ResourceBundle bundle = ResourceBundle
.getBundle("resource.DbProperties");
String logPath = bundle.getString("logs.path");
File filePath = new File(logPath);
if (!filePath.exists()) {
filePath.mkdirs();
}
props.clone();
props = getPropsFile(propertyFile, className);
props.setProperty("info_file_path", filePath.toString());
// PropertyConfigurator.configure(props);
} catch (Exception e) {
e.printStackTrace();
}
return props;
}
public void info(String message) {
logger.info(message);
}
public void warn(String message) {
logger.warn(message);
}
public void error(String message) {
logger.error(message);
}
public void fatal(String message) {
logger.fatal(message);
}
public void printStackTrace(Throwable ex) {
StringWriter sw = new StringWriter();
ex.printStackTrace(new PrintWriter(sw));
logger.error("\n" + sw.toString());
}
log4j.properties
log4j.rootCategory=LOGFILE
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
log4j.appender.LOGFILE.File=${info_file_path}\\info_Pension_application.log
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.Threshold=INFO
log4j.appender.LOGFILE.Threshold=DEBUG
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
If your "simple Java class" happens to be in a Java EE container (like a .jsp or servlet in Tomcat, JBoss or WebSphere), then all you need to do is:
1) import org.apache.log4j.Logger;
2) declare a static instance in your class:
EXAMPLE: `static Logger logger = Logger.getLogger ("MyApp");`
3) Use your logger
EXAMPLE: `logger.info ("something interesting happened");`
4) If you include log4j.java and your own log4j.properties in your CLASSPATH, then you don't need to do anything else.
Here's a bit more info on using log4j with Tomcat or app servers:
http://tomcat.apache.org/tomcat-5.5-doc/logging.html
http://logging.apache.org/log4j/1.2/manual.html
http://www.tutorialspoint.com/log4j/log4j_quick_guide.htm
Here's a very simple example program that "does logging", from the above tutorialspoint.com link:
import org.apache.log4j.Logger;
import java.io.*;
import java.sql.SQLException;
import java.util.*;
public class log4jExample{
/* Get actual class name to be printed on */
static Logger log = Logger.getLogger(
log4jExample.class.getName());
public static void main(String[] args)
throws IOException,SQLException{
log.debug("Hello this is an debug message");
log.info("Hello this is an info message");
}
}