I'm new to java and trying to learn how to log an exception by example. I found the following example code here:
http://www.kodejava.org/examples/447.html
However, I don't see where the filename for the log file is specified. When I research the question on Google usually people refer to the framework used for programming java to figure out where the log file gets stored. However, I'm not using a framework. I'm just creating my java files using VIM editor from the command line. The java file sits on an Linux CentOS application server and is called from a client's browser.
Question 1: Is it possible to modify the example below to include a file name and path for logging? Or, am I way off base with this question?
Question 2: Even though I log the exception, will it still propagate to the client for the user to view? Hopefully it will, otherwise the user won't know an error has occurred.
package org.kodejava.example.util.logging;
import java.util.logging.Logger;
import java.util.logging.Level;
import java.util.Date;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.text.ParseException;
public class LoggingException {
private static Logger logger = Logger.getLogger(LoggingException.class.getName());
public static void main(String[] args) {
DateFormat df = new SimpleDateFormat("dd/MM/yyyy");
df.setLenient(false);
try {
//
// Try to parsing a wrong date.
//
Date date = df.parse("12/30/1990");
System.out.println("Date = " + date);
} catch (ParseException e) {
//
// Create a Level.SEVERE logging message
//
if (logger.isLoggable(Level.SEVERE)) {
logger.log(Level.SEVERE, "Error parsing date", e);
}
}
}
}
Try this:
try {
FileHandler handler = new FileHandler("myLogFile.log", true);
Logger logger = Logger.getLogger(LoggingException.class.getName());
logger.addHandler(handler);
} catch (IOException e) {
logger.log(Level.SEVERE, "Error parsing date", e);
}
By default, a file handler overwrites the contents of the log file each time it is created. You might also want to append log file so in FileHandler constructor you need to specify true as a second parameter.
Hope this helps.
EDIT:
package org.kodejava.example.util.logging;
import java.util.logging.Logger;
import java.util.logging.Level;
import java.util.Date;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.text.ParseException;
public class LoggingException {
private static Logger logger = Logger.getLogger(LoggingException.class.getName());
public static void main(String[] args) {
DateFormat df = new SimpleDateFormat("dd/MM/yyyy");
df.setLenient(false);
FileHandler handler = new FileHandler("myLogFile.log", true);
logger.addHandler(handler);
try {
//
// Try to parsing a wrong date.
//
Date date = df.parse("12/30/1990");
System.out.println("Date = " + date);
} catch (ParseException e) {
//
// Create a Level.SEVERE logging message
//
if (logger.isLoggable(Level.SEVERE)) {
logger.log(Level.SEVERE, "Error parsing date", e);
}
}
}
}
This should work. I did not test it.
More efficient way would be create a method to initialize logger and add handler to it. But I will mostly recommend you to think about using log4j. It is easy to set up and widely used logging framework.
You need a FileHandler attached to the log, which you can add manually somewhere in your initialization, or configure your logging with a .properties file.
(p.s. the isLoggable call in this example is redundant and only bloats the code)
Add a file handler for the logger in the config.
Link: http://www.crazysquirrel.com/computing/java/logging.jspx
handlers = java.util.logging.ConsoleHandler, java.util.logging.FileHandler
Better go with log4j. It a good logging framework.
Related
I am very new to java and coding so please understand that I am very naive when it comes to this stuff.
I am trying to get Java to write logs to a .txt file. I have been researching this for hours and my brain hurts too much to keep looking. I am hoping you guys can look at this and tell me what is wrong. Below is the code. This is being written on my Mac for the time being but ultimately I will have it run on Windows.
import java.util.logging.FileHandler;
import java.util.logging.Logger;
import java.util.logging.Level;
public class WriteLogEntriesToLogFile extends Login {
public WriteLogEntriesToLogFile(String[] args) throws Exception {
boolean append = true;
FileHandler handler = new FileHandler("Test.logon.log.txt");
Logger logger = Logger.getLogger("/Downloads/log.txt");
logger.addHandler(handler);
logger.severe("severe message");
logger.warning("warning message");
logger.info("info message");
logger.config("config message");
logger.fine("fine message");
logger.finer("finer message");
logger.finest("finest message");
}
}
I definitely feel like I am missing something (or a lot of somethings). Any assistance is appreciated!
From what I could tell your logging was outputting to a file and seemed to be working.
However, I noticed the logs were difficult to parse due to the format being xml-record based, so I used a SimpleFormatter in my solution to read the logs at a line level.
Solution:
public static void main(String[] args) {
Logger logger = Logger.getLogger("");
FileHandler fileHandler;
try {
fileHandler = new FileHandler("Test.logon.log.txt");
logger.addHandler(fileHandler);
SimpleFormatter formatter = new SimpleFormatter();
fileHandler.setFormatter(formatter);
logger.info("0.0 - My first log");
logger.info("1.0 - Test log");
} catch (SecurityException | IOException e) {
e.printStackTrace();
}
}
I hope this helps.
I am trying to log the program's execution flow to better understand how servlets, EJBs and JSPs work together.
Currently the difficulty I am facing is to output the log to a local file.
I have first tried with the Java logger API, studying this example:
Using Java log API:
http://wiki4.caucho.com/Java_EE_Servlet/JSP_tutorial_:_Adding_an_error_page,_logging,_and_other_forms_of_debugging#Using_Java_log_API
And I have written:
package beans;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.Stateless;
#Stateless
public class ComentarioNota {
private static final Logger log = Logger.getLogger(ComentarioNota.class.getName());
public String convierteComentarioNota(String evaluacion, String comentario) {
log.logp(Level.WARNING,
this.getClass().getName(),
this.getClass().getName(), this.getClass().getName() + "::convierteComentarioNota::el usuario introdujo: " + evaluacion + comentario);
if (evaluacion.trim().equals("Apto") && comentario != null && comentario.length() > 5) {
return "Apto";
} else {
return "No Apto";
}
}
And it indeed outputs the log with ClassName::ClassMethod::User input info.
However it outputs the log info to the console, I need it in a local file, how could we log into a local file?
I have tried to use the PrintWriter and creating a new file with its contents:
package beans;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.Stateless;
#Stateless
public class ComentarioNota {
private static final Logger log = Logger.getLogger(ComentarioNota.class.getName());
public String convierteComentarioNota(String evaluacion, String comentario) {
try (PrintWriter out = new PrintWriter("log.txt")) {
out.println(this.getClass().getName() + "::convierteComentarioNota::el usuario introdujo: " + evaluacion + comentario);
if (evaluacion.trim().equals("Apto") && comentario != null && comentario.length() > 5) {
return "Apto";
} else {
return "No Apto";
}
} catch (FileNotFoundException ex) {
Logger.getLogger(ComentarioNota.class.getName()).log(Level.SEVERE, null, ex);
}
return "No Apto";
}
}
However this does not create a new file.
How could we create that new local file and send the log output to it?
Thank you for your help!.
I have also read:
How do I save a String to a text file using Java?
Where does the ServletContext.log messages go in tomcat 7?
EDIT: I have read the comment's tutorial: http://tutorials.jenkov.com/java-logging/handlers.html#streamhandler
ANd I have found that we can add handlers to the logger, and there is a built in handler which is FileHandler which is supposed to create one file with the log's contents. I have tried the following:
package beans;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.Stateless;
#Stateless
public class ComentarioNota {
private static final Logger log = Logger.getLogger(ComentarioNota.class.getName());
public String convierteComentarioNota(String evaluacion, String comentario) {
try {
FileHandler handler = new FileHandler("comentarioNota.txt");
log.addHandler(handler);
log.logp(Level.WARNING,
this.getClass().getName(),
"convierteComentarioNota", this.getClass().getName() + "::convierteComentarioNota::el usuario introdujo: " + evaluacion + comentario);
if (evaluacion.trim().equals("Apto") && comentario != null && comentario.length() > 5) {
return "Apto";
} else {
return "No Apto";
}
} catch (IOException ex) {
Logger.getLogger(ComentarioNota.class.getName()).log(Level.SEVERE, null, ex);
} catch (SecurityException ex) {
Logger.getLogger(ComentarioNota.class.getName()).log(Level.SEVERE, null, ex);
}
return "No Apto";
}
}
However I still seeing the log being outputted to the console and no file is being created:
And no file is being creted because at least it does not show up in the IDE and I have also try to find it:
Could you help me figuring out how to log to a local file properly?
Thank you for your help.
you need to configure java.util.logging. what you're looking for is the FileHandler. I actually prefer other logging APIs but for your purposes please start here: Tutorial: Java Logging Configuration
I'm trying to use the printWorkingDirectory() from Apache Commons FTP but it's only returning null. I can't navigate directories, list files, etc.
Log in pass all is success but how ever I try I can not change current directory.
I use this following code:
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
public class FTPDownloadFileDemo {
public static void main(String[] args) {
String server = "FTP server Address";
int port = portNo;
String user = "User Name";
String pass = "Pasword";
FTPClient ftpClient = new FTPClient();
String dir = "stocks/";
try {
ftpClient.connect(server, port);
ftpClient.login(user, pass);
System.out.println( ftpClient.printWorkingDirectory());//Always null
//change current directory
ftpClient.changeWorkingDirectory(dir);
boolean success = ftpClient.changeWorkingDirectory(dir);
// showServerReply(ftpClient);
if (success)// never success
System.out.println("Successfully changed working directory.");
System.out.println(ftpClient.printWorkingDirectory());// Always null
} catch (IOException ex) {
System.out.println("Error: " + ex.getMessage());
ex.printStackTrace();
} finally {
try {
if (ftpClient.isConnected()) {
ftpClient.logout();
ftpClient.disconnect();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
This is rather old question that deserves an answer. This issue is likely a result of using FTPClient when secure connection is required. You may have to switch to FTPSClient if that is, indeed, the case. Further, output the response from the server with the following code snippet to troubleshoot the issue if secure client doesn't solve the it:
ftpClient.addProtocolCommandListener(
new PrintCommandListener(
new PrintWriter(new OutputStreamWriter(System.out, "UTF-8")), true));
Also, a server can reject your login attempt if your IP address is not white listed. So, being able to see the logs is imperative. The reason you see null when printing current working directory is because you are not logged in. Login method will not throw an exception but rather return a boolean value indicating if the operation succeeded. You are checking for success when changing a directory but not doing so when logging in.
boolean success = ftpClient.login(user, pass);
I faced the same, but I came across with a simple step.
Just added this.
boolean success = ftpClient.changeWorkingDirectory(dir);
ftpClient.printWorkingDirectory(); //add this line after changing the working directory
System.out.println(ftpClient.printWorkingDirectory()); //wont be getting null
Here I have the code and the console output
FTPClient.changeWorkingDirectory - Unknown parser type: "/Path" is current directory
I know I replied too soon ;-P, but I saw this post recently. Hope this helps to future searchers ;-)
I am currently learning to develop in Java and am interested in creating Java classes that other users can import into their program and use. Yes, I know my example class is simple and stupid but I want to learn the concept and start making more complex classes that people can import into their projects.
I created a simple "Logger" class that when called logs both text to the console and to a text file for readability. You can call this class by using the following commands...
Logger Logger = new Logger();
Logger.create();
Logger.log("This text will be logged to the console and log.log");
See below for the Logger class.
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class Logger {
FileWriter fw;
BufferedWriter br;
File file = new File("log.log");
boolean fileExists = file.exists();
public void log(String message) {
try {
fw = new FileWriter(file, true);
br = new BufferedWriter(fw);
Calendar cal = Calendar.getInstance();
int hour = cal.get(Calendar.HOUR_OF_DAY);
if(hour > 12)
hour = hour - 12;
int minute = cal.get(Calendar.MINUTE);
int second = cal.get(Calendar.SECOND);
int millis = cal.get(Calendar.MILLISECOND);
int ampm = cal.get(Calendar.AM_PM);
String ampmString;
if(ampm == 1)
ampmString = "PM";
else
ampmString = "AM";
String now = String.format("%02d:%02d:%02d.%03d %s", hour, minute, second, millis, ampmString);
System.out.println(now + " - " + message);
br.write(now + " - " + message);
br.newLine();
br.close();
} catch (Exception err) {
System.out.println("Error");
}
}
public void create() {
try {
fw = new FileWriter(file, true);
br = new BufferedWriter(fw);
SimpleDateFormat sdf = new SimpleDateFormat("MM-dd-YYYY");
String dateString = sdf.format(new Date());
if(file.length() != 0)
br.newLine();
System.out.println("Log: " + file.getAbsolutePath());
br.write("--------------------" + dateString + "--------------------");
br.newLine();
br.close();
} catch (Exception err) {
System.out.println("Error");
}
}
}
The issue I am having is in order to use this class I have to add it to every single project I create and want to use this. Is there a way I can add an import like, mydomain.Logger.*; and be able to access this class and the methods it contains?
My question, What is the best way to allow anyone to import/use my Logger class in the simplest way? What steps do I need to take to allow them to do this?
Compile your class into a JAR file, and then add that jar to the classpath of each project. This is the standard Java approach to reusing classes.
Each class has a package. You declare it on the top of your file. For your class this could be i.e. package com.mydomain;. (Your example does not declare a package so the default is assigned - think "none"). Packages correspond to actual folders e.g. you should place your Logger.java in the path com/mydomain/ in your file system to match a package declaration like the one above.
Now if you create a class in the same package you could use your Logger class by just declaring a variable like in your example. No imports necessary.
If you create the new class in a different package i.e. com.otherdomain (this means that it would actually be in a different folder in the file system) then you would have to use an import statement like this: import com.mydomain.Logger; or import com.mydomain.*; otherwise the compiler would show an error and wouldn't let you use your Logger class.
If you would like to let other people use your class you would probably ship your binary version (i.e. the compiled Logger.class) not the source. And you would probably put that file in a jar (this is a zipped file structure more or less).
If then I wanted to use your class I could just add that jar to the classapth of my project, so the compiler and the runtime system would know to search this file when looking for classes. I would be able then to write an import statement myself inside my class and I could use your logger.
I hope this clears things up
You will have to create a jar file, then people can import that into their projects.
The Scala language lets you import members of arbitrary objects, but Java will only let you import static members. You can try using static imports. However, you'd need to change your Logger class to have a static log method. Since you probably just want a single instance of your logger, I'd recommend using the singleton enum pattern:
// Using "enum" instead of "class"
public enum Logger {
// Create singleton instance
INSTANCE;
// Create static log method for export
public static void log(String message) {
INSTANCE.log(message);
}
// The rest of your class is unchanged
FileWriter fw;
BufferedWriter br;
File file = new File("log.log");
boolean fileExists = file.exists();
public void log(String message) {
// ...
}
public void create() {
// ...
}
}
Now in each file you want to use it you can just do import static mydomain.Logger.log; to get direct access to the log method!
I have a JNLP downloader application deployed on remote user machines that downloads files.
I need to get some error feedback mailed to me. Not so much exceptions, just things getting stuck, or stalled or in infinite loops.
Currently I have a basic handler:
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.Logger;
public class javaerrorlog {
private static Logger l = Logger.getLogger("");
public static void main(String args[]) throws Exception{
FileHandler handler = new FileHandler("log.txt");
l.addHandler(handler);
l.setLevel(Level.ALL);
l.info("Error logs");
try {
} catch (Error ex) {
l.log(Level.INFO, "", ex);
}
l.fine("");
}
}
Also, should I prompt for the client's permission to send error reporting data?
If you just need notifications you could use something like SMTPHandler. If you need it more fancy you could use JMS with an MDB.