Java Logging to Multiple Files - java

I have an application which keeps track of multiple students. When processing infromation on that student, I want their log messages to go into that log file.
logs/system.log
logs/abby.log
logs/brett.log
logs/catherine.log
The system can add more students dynamically, so I can't specify each student in my log config file. How can I, at runtime, specify that a logger should write information to catherine.log ?

Which Logging Framework are you using? Here is an example if you are using Log4j:
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.SimpleLayout;
import org.apache.log4j.FileAppender;
public class MyTestClass {
/* Logger Instance should always be kept static final */
private static final Logger LOGGER = Logger.getLogger(MyTestClass.class);
public static void main(String args[]) {
/* Create Dynamic FileAppender */
SimpleLayout myLayout = new SimpleLayout();
FileAppender nwAppender = new FileAppender(myLayout,"file_nm",false);
LOGGER.addAppender(nwAppender);
LOGGER.setLevel((Level) Level.INFO);
/* Write Level : Debug */
LOGGER.debug("*** DEBUG ***");
/* Write Level : Info */
LOGGER.info("*** INFO ***");
/* Write Level : Error */
LOGGER.info("*** ERROR ***");
}
}

How can I, at runtime, specify that a logger should write information to catherine.log ?
There is no logging.properties option to enable this behavior. You have to write code to create a logger (strongly referenced) and installed a FileHandler on that logger.
Messages for abby.log are simultaneously written to the system log and to abby.log.
You should create a logger namespace such that the system file handler is installed on the root logger and each student is a child logger with setUseParentHandlers set to false.
If multiple threads are processing abby, it will open up abby-1, abby-2
That is because you are created multiple FileHandlers with the same file name. Create a Map and remember what you have opened.

Related

log4j2 log file created even when Level is OFF?

I have a global logger which is used in a few classes so that I can log everything in a single file. All works good, however I want to be able to disable the Logger from UI. I tried setting the Level to OFF like shown below, which stops the logging but an empty log file is still created ( I am using File Appender with the logger).
Is there any easy way to avoid creating the log file when Level is OFF ?
public class Main {
public static Logger LOGGER = LogManager.getLogger("GLOBAL");
public static void main(String[] args) {
Configurator.setLevel("GLOBAL", Level.OFF);
//Rest of code
}
}
The LogManager.getLogger("GLOBAL") creates the log file while reading the log4j configuration and initializing it. So, there is no way you can stop it from doing it when you are at Configurator.setLevel("GLOBAL", Level.OFF);. IMO, you have 2 options:
1) Elegant way: Initialize the LogManager in your code by passing the configuration at runtime LogManager.getLogManager().readConfiguration. You could refer here for detailed implementation.
2) Ugly way: Delete the log file when you set the LEVEL.OFF

Logger working in one file but in another

I have my package structures defined as follows for a dependency named MyProjectwhich is used in another maven project:
In the application.properties file, I have the level for loggers on classes inside the root package defined as follows:
logging.level.abc.xyz.registry=DEBUG
env=DEV
email_to=myname#example.com
I have some logger.info("Test")defined in the following file and I can see them printing on the console.
Myproject/src/main/java/abc/xyz/registry/orm/dao/impl/File1DaoImpl.java
I have some logger.info("Test") and logger.debug("Test") defined in the following file as well. However,I cannot see the logger printing any information on the console :
Myproject/src/main/java/abc/xyz/registry/orm/dao/impl/File2DaoImpl.java
Any reason why this is happening?
Logger Declarations in both the classes :
private static final Logger logger = LoggerFactory.getLogger(File1DaoImpl.class);
private static final Logger logger = LoggerFactory.getLogger(File2DaoImpl.class);
File1DaoImpl has logger defined in the following manner(Basically I am not printing any variables here and just messages)
logger.info("Starting Insert method in Eclipse May 22 File1DaoImpl.insert() .....");
I have it defined like the following in File2DaoImpl which doesn't works:
logger.debug("Records Updated in File2DaoImpl params : " +
"employeeId:"+employeeId+
",tokenID:"+tokenID+
",newEmpID:"+newEmpID+
",userComments="+userComments
);
logger.info("INSERTED Records from the File2DaoImpl:"+
"employeeId:"+employeeId+
",tokenID:"+tokenID+
",newEmpID:"+newEmpID+
",userComments="+userComments
);
I have following import statements in both the classes:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Where does my Log4J output go to(ran the HelloWorld Log4J example)?

I'm trying to learn Log4J and have a problem with understanding how to incorporate the logging and view output. This is my code:
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class HelloWorldLog4J {
private static final Logger logger = LogManager.getLogger("HelloWorld");
public static void main(String[] args) {
logger.info("Hello, World! ammmm");
}
}
Where does the output go to ? I assume that there's some text file in the log4j install-directory?
This is how my log4J directories looks like
You need to post your log4j.properties file. In many cases , this is how specify the output file in log4j.properties file :-
log4j.appender.outLogger.File=appname-out.log # normal output
log4j.appender.errLogger.File=appname-err.log # Error due to logger.error

Using java.util.logging.Logger in a jar file that will be displayed in LogCat in Android

Android Studio 0.8.1
java version "1.7.0_60"
Hello,
I have created a jar file and calling this from my Android App. For testing purposed I want to put some logging in the jar file that will be displayed in the LogCat window.
I have decided to use Java's java.util.logging.Logger class. However, when I run my app with No Filter I cannot see any of my log messages being displayed.
import java.util.logging.ConsoleHandler;
import java.util.logging.SimpleFormatter;
import java.util.logging.Handler;
import java.util.logging.Logger;
import java.util.logging.Level;
public class RequestFactory extends WebServiceRequestFactory {
private static final Logger log = Logger.getLogger("RequestFactory");
public RequestFactory() {
ConsoleHandler consoleHandler = new ConsoleHandler();
log.addHandler(consoleHandler);
consoleHandler.setFormatter(new SimpleFormatter());
log.log(Level.FINE, "LOG: Initialized overloaded constructor");
System.out.println("Initialized overloaded constructor");
}
.....
I have set the above to be displayed in the Console. However, the System.out.println always prints out. However, I don't want to use the System.out.println for displaying logs messages.
If possible I would like to stick to java's logging class.
In the LogCat window I can see the System.out.println(...), but not the log.log(...) one:
I/System.outīš• Initialized overloaded constructor
Am I doing something wrong here?
Many thanks for any suggestions
The default level for the ConsoleHandler is INFO. The default level for the logger is inherited from its parent. By default, the root logger is usually set to INFO. A FINE log message will not be reported using the default settings. Change the log level of the ConsoleHandler to ALL and change the level of the logger to FINE.
log.setLevel(Level.FINE);
consoleHandler.setLevel(Level.ALL);

Is it possible to change the log4j level in my packages but not change the levels in api's im using e.g spring

So I have this code:
public class LoggingManager {
Logger root = Logger.getRootLogger();
public void setLogger(String fullClassName, String level) {
LogManager.getLogger(fullClassName).setLevel(Level.toLevel(level));
}
public void logLevelAll(String level) {
root.setLevel(Level.toLevel(level));
}
}
My problem is this. The first method takes in values: p1: com.domain.data.Object and p2: DEBUG and will change that classes log level to debug. The second class will change every logger in the project including libraries referenced like spring.
I want to create a method that only changes the logging level of my packages. So changes com.domain.* if you like.
Can this be done?
Simply set the log level for com.domain. By default each logger will inherit the log level from its parent logger.
Just realised that. Here is the full answer I got for others:
Log4j provides a default root logger that all user-defined loggers inherit from. Root logger is at the top of the logger hierarchy; in other words, root logger is either parent or ancestor of all logger objects created.
For example: A class 'MyClass' in com.domain.sampleapp application package can have a logger named com.domain.sampleapp.MyClass you can use my method above to set the class:
LogManager.getLogger("com.domain.sampleapp.MyClass").setLevel(Level.toLevel("DEBUG"));
But you can also set the package log level like so:
LogManager.getLogger("com.domain.sampleapp").setLevel(Level.toLevel("DEBUG"));
And finally you could set a whole group of packages (i.e ur whole project) by using:
LogManager.getLogger("com.domain").setLevel(Level.toLevel("DEBUG"));

Categories

Resources