I have a logger code in Java. It is not creating a log file. Though when I am using Logger.println in another class it is printing. But I am not sure if it is logging or not.
I have written a logger class and I am using this in another class to log my code.
My logger class looks like below:
public class Logger{
private static String logFile=null;
public static boolean setLogFile(String newLogFile, Boolean b){
boolean done = false;
if (logFile ==null){
logFile = newLogFile;
File file = new File(logFile);
try{
done = file.createNewFile();
}
catch(IOException e){Logger.println("Error in creating log file" +logFile);
}
}
else {
File fromFile = new File(logFile);
File toFile = new File(newLogFile);
if(fromFile.exists()){
done = fromFile.renameTo(tofile);
if (done){
logFile = newLogFile;
}
else{
logger.println("can not move file");
}
}else{
Logger.println("file not exist";
}}
return done;
}
public static void print(String data){
system.out.println(data);
try{
FileWriter logger = new FileWriter (logFile, true);
logger.write(data);
logger.close();
}
catch(IOException e){System.out.println("can not write to file");
}}
where is logger.print saving to?
where are the logs being saved or how can i specify the location of my logs?
You no need to reinvent the wheel again. You can easily integrate one of the loggers that can write a log file at your convenient location.
Try Log4j, SL4j or available dependencies based on your need.
These existing implementations give you fine-grained loggings. You can print info, error, debug, config and warnings. It would be easier to integrate as well as developer can concentrate on business logic.
Related
I configure my application to use a logging class rather than the logging.properties file in the jre conf folder using -Djava.util.logging.config.class=com.jthink.songkong.logging.StandardLogging
And it works, except that I notice that information that is just mean to be going to my log file is also going to console window, this is being noticed when using --win-console with jpackage on Windows but I think it was already happening before I was using JPackage
This is my logging class:
public final class StandardLogging
{
public static int LOG_SIZE_IN_BYTES = 10000000;
//Default parent logger
public static Logger defaultLogger = Logger.getLogger("");
//jaudiotagger logger
public static Logger ioLogger = Logger.getLogger("org.jaudiotagger");
//SongKong logger
public static Logger debugLogger = Logger.getLogger("com.jthink");
//SongKong usaer Message Logger
public static Logger userInfoLogger = Logger.getLogger("com.jthink.songkong.ui.MainWindow");
//General c3p0
public static Logger c3p0Logger = Logger.getLogger("com.mchange.v2.c3p0");
//For capturing Preapred stament Cache hits
//public static Logger c3p0ConnectionLogger = Logger.getLogger("com.mchange.v2.c3p0.stmt");
//For capturing stack traces when connection lasted too long
public static Logger c3p0PooledConnectionLogger = Logger.getLogger("com.mchange.v2.resourcepool.BasicResourcePool");
//HIbernate SQL
public static Logger hibernateLogger = Logger.getLogger("org.hibernate.SQL");
//TODO not sure this even used, I think CmdLogger just does System.out
private static Logger cmdlineLogger = Logger.getLogger("cmdline");
protected void configureLoggerLevels()
{
//Default Log Level, used by any 3rd party libs we are using if not configured further
defaultLogger.setLevel(Level.WARNING);
//For Debug (songKong and jaudiotagger)
ioLogger.setLevel(Level.WARNING);
ioLogger.setUseParentHandlers(false);
try
{
//If GeneralPreferences exist and we can access set from user value
ioLogger.setLevel(Level.parse(String.valueOf(GeneralPreferences.getInstance().getIoDebugLevel())));
}
catch(Exception ex)
{
}
debugLogger.setLevel(Level.WARNING);
debugLogger.setUseParentHandlers(false);
try
{
//If GeneralPreferences exist and we cBuildBuiklan access set from user value
debugLogger.setLevel(Level.parse(String.valueOf(GeneralPreferences.getInstance().getDebugLevel())));
}
catch(Exception ex)
{
}
//C3p0 Logger
c3p0Logger.setLevel(Level.INFO);
c3p0Logger.setUseParentHandlers(false);
//Set to FINEST to see SQL
hibernateLogger.setLevel(Level.WARNING);
hibernateLogger.setUseParentHandlers(false);
//For Capturing CheckIn/Outs nad Prepared Statement Cache Hits
//c3p0ConnectionLogger.setLevel(Level.FINEST);
//c3p0ConnectionLogger.setUseParentHandlers(false);
//For capturing stacktrace from timed out connections
c3p0PooledConnectionLogger.setLevel(Level.INFO);
c3p0PooledConnectionLogger.setUseParentHandlers(false);
//For user message log
userInfoLogger.setUseParentHandlers(false);
userInfoLogger.setLevel(Level.FINEST);
userInfoLogger.setUseParentHandlers(false);
userInfoLogger.setLevel(Level.FINEST);
}
protected void configureHandlers() throws Exception
{
//Set Filehandler used for writing to debug log
String logFileName = Platform.getPlatformLogFolderInLogfileFormat() + "songkong_debug%u-%g.log";
FileHandler fe = new FileHandler(logFileName, LOG_SIZE_IN_BYTES, 10, true);
fe.setEncoding(StandardCharsets.UTF_8.name());
fe.setFormatter(new LogFormatter());
fe.setLevel(Level.FINEST);
//Set Filehandler used for writing to user log
String userLogFileName = Platform.getPlatformLogFolderInLogfileFormat() + "songkong_user%u-%g.log";
FileHandler userFe = new FileHandler(userLogFileName, LOG_SIZE_IN_BYTES, 10, true);
userFe.setFormatter(new com.jthink.songkong.logging.UserLogFormatter());
userFe.setLevel(Level.FINEST);
//Write this output to debug log file
//defaultLogger.addHandler(fe);
c3p0Logger.addHandler(fe);
c3p0PooledConnectionLogger.addHandler(fe);
//c3p0ConnectionLogger.addHandler(fe);
ioLogger.addHandler(fe);
debugLogger.addHandler(fe);
hibernateLogger.addHandler(fe);
//Write this output to user log file
userInfoLogger.addHandler(userFe);
//For cmd line output, is this still used
cmdlineLogger.setUseParentHandlers(false);
ConsoleHandler cmdLineHandler = new java.util.logging.ConsoleHandler();
cmdLineHandler.setLevel(Level.FINEST);
cmdLineHandler.setFormatter(new CmdLineFormatter());
cmdlineLogger.addHandler(cmdLineHandler);
System.out.println("debuglogfile is:" + logFileName);
System.out.println("userlogfile is:" + userLogFileName);
}
public StandardLogging()
{
try
{
configureLoggerLevels();
configureHandlers();
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
}
And this is an example of code that I would just expect to go to my songkong-debug0-0.log file, but it is also being output to the console window:
MainWindow.logger.warning("User Dir:"+ System.getProperty("user.dir"));
MainWindow.logger.warning("Java Dir:"+ System.getProperty("java.home"));
Why would that be?
Add code to com.jthink.songkong.logging.StandardLogging to print the logger tree at the end of your configuration. This will help you troubleshoot what is happening. Since you are using a configuration class you can even make your own system property to toggle printing the logger tree if you need to in the future.
If your console output looks like the format of the CmdLineFormatter you created then code is either using that logger or a child logger that is printing to the parent handlers. Assuming you control the format of the CmdLineFormatter you can include the logger name in the output to locate the logger in question.
If the output looks like the SimpleFormatter then more likely it is the console handler that is attached to the root logger. Simply remove that handler from the root logger in your configuration class.
A more complete solution is to invoke LogManager.reset at the start of your StandardLogging class constructor. This would clear out the configuration that the JRE set prior to invoking your changes. An alternative is to set the java.util.logging.config.file to point to a null device from the command line in addition to setting your java.util.logging.config.class.
I am writing an API service that fetches data from a stream, and outputs it in a file. I can't output it as a stream because I use Swagger (now OpenAPI) 2.0, which doesn't support output streams (Swagger 3.0 does, but i can't use it).
What would be the cleanest way to make a file, output it via the service, and then make sure it gets deleted?
I initially thought I might use a temp file and delete in finally clause. However, there is no guarantee that the file finished downloading on the client side before that clause is reached and file is deleted.
Am I right? Wrong? Is there a better way to do this?
I was talking about using a closeable in the comments. This is it.
Usage:
try (TempFile file = new TempFile("tempfile", ".txt")) {
// do stuff with file
} catch (IOException e) {
// error handling.
// file should be automatically deleted.
}
TempFile:
public class TempFile implements AutoCloseable {
private final File file;
public TempFile(String prefix, String suffix) {
this.file = File.createTempFile(prefix, suffix);
}
public File getFile() {
return this.file;
}
#Override
public void close() throws IOException {
this.file.delete();
}
}
I can't seem to find a way to store a simple scoring system for a user identifier and their score. I've tried storing it in a string and in a file, but I couldn't get it to work properly.
Here's the relevant code
public class ShiftGame extends JavaPlugin implements Listener {
public void onEnable() {
getServer().getPluginManager().registerEvents(this, this);
}
#EventHandler
public void onPlayerSneak(PlayerToggleSneakEvent e){
Player player = e.getPlayer();
String name = player.getDisplayName();
if(e.isSneaking() == false){
try {
PrintWriter out;
System.out.println("Writing to data file..");
out = new PrintWriter("PlayerShiftAmounts.txt");
out.println(name);
out.close();
} catch (FileNotFoundException e1) {
e1.printStackTrace();
}
}
}
}
Minecraft has some config file class: FileConfiguration and YamlConfiguration, so I think you don't need to use java.io.*, and realy needn't to worry about file writing.
FileConfiguration config = YamlConfiguration.loadConfiguration(file);
If you sure have to log something many times a second , I think you should try to use cache or just make a variable in Java , instead of writing into file or database every time.. I don't know why you need to log a list of which player are pressing shift?
I'm learning this logger from java and trying to call the class MyLogger from the main class but it seems not to be working
MyLogger.java
public class MyLogger {
public MyLogger() {
Logger logger = Logger.getLogger("MyLog");
FileHandler fh;
try {
fh = new FileHandler("c:\\opt\\MyLogFile.log", true);
logger.addHandler(fh);
logger.setLevel(Level.ALL);
SimpleFormatter formatter = new SimpleFormatter();
fh.setFormatter(formatter);
logger.log(Level.WARNING,"My first log");
} catch (SecurityException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Client.java
public class Client {
private final static Logger LOGGER = Logger.getLogger(Client.class.getName());
public static void main(String[] args) {
LOGGER.setLevel(Level.SEVERE);
LOGGER.getName();
LOGGER.getClass();
LOGGER.info("ABC");
}
}
Why is it not calling the MyLogger.java to create the log file?
Is there a beter way to log the eclipse console rather than putting LOGGER on each methods for each class?
Why some uses flush() before closing the log file?
Why is it not calling the MyLogger.java to create the log file?
If it refers to running Client, then that's because there is no relation between that class and your MyLogger class.
Is there a beter way to log the eclipse console rather than putting
LOGGER on each methods for each class?
Better is very subjective. The majority of source code I've seen use the paradigm you're using in your Client class. That is, declaring a static final Logger with the name of enclosing class and using it where you need to log something within that class.
Some applications make use of AOP concepts for logging.
Why some uses flush() before closing the log file?
Some implementations may buffer log messages so as not to make many small IO system calls, but instead make few big ones. Closing the log file may not flush the buffer, so you'll want to flush it explicitly.
I would like to record the logs of my Java application.
I have created this class:
public class Log {
final Logger logger = Logger.getLogger("DigiScope.log");
public static void main(String[] args) {
}
public Log(String message) {
try {
// Create an appending file handler
boolean append = true;
FileHandler handler = new FileHandler("my.log", append);
// Add to the desired logger
Logger logger = Logger.getLogger("com.mycompany");
logger.addHandler(handler);
logger.info(message);
} catch (IOException e) {
}
}
}
And for each button I have a code like that:
private void btnNewPatient ActionPerformed(java.awt.event.ActionEvent evt) {
Log a = new Log("New Patient created");
}
This code creates a log.txt, but records only the click on the first button, the others clicks on the others buttons are not record.
Can you help me?
Thank you.
It doesn't make much sense to create a proprietary logging wrapper in your app - java.util.logging is already such a wrapper, so I recommend using it directly. You should create logger objects in your classes, then log messages within handler methods something like this:
logger.info("New Patient created");
And you should use the same Logger instance throughout your class, instead of creating new instances all the time. The standard way is to create one static final instance per class.
It is also better to configure logging from a config file, not from code.
I recommend reading through the Java Logging Tutorial.
Péter Török and StriplingWarrior are right with their suggestion to use the Logging framework in the right way:
logger.info("New Patient created");
instead of creating a new Logger for each statement.
But even with your construction, you should have a logfile with all logging information.
For each invocation of the Log constructor, a new my.log.X file is created (X is a number). And from this point in time each log statement is logged in this file.
So if you invoke the constructor three times (with message: "first", "second", "third") then you should have the files: my.log, my.log.1. my.log.2
my.log: "first", "second", "third"
my.log.1: "second", "third"
my.log.2: "third"
I'm guessing that it's probably logging each click, but you're reopening the file with each new log message, rather than appending to it.