Java Logger wont log - java

Was able to print some stuff in the logfile by studying and modifying some sample codes but while running the package nothing is being printed to the logfile.
Main Class (Client.java)
public class Client {
static Logger LOGGER = Logger.getLogger(Client.class.getName());
public static void main(String[] args) {
Client logger = new Client();
try {
LogSetup.setup();
emsSession = logger.Initialise();
logger.getAllMEInfo();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("Problems with creating the log files");
}
}
private void getAllMEInfo() {
LOGGER.setLevel(Level.INFO);
LOGGER.severe("Info Log");
LOGGER.warning("Info Log");
LOGGER.info("Info Log");
LOGGER.finest("Really not important");
// Some codes for the method
}
}
LogSetup.java
import java.io.IOException;
import java.text.ParseException;
import java.util.logging.ConsoleHandler;
import java.util.logging.FileHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;
public class LogSetup {
static private FileHandler fileTxt;
static private LogWriter formatterTxt;
static public void setup() throws IOException, ParseException {
Logger logger = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
Logger rootLogger = Logger.getLogger("");
Handler[] handlers = rootLogger.getHandlers();
if (handlers[0] instanceof ConsoleHandler) {
logger.removeHandler(handlers[0]);
}
logger.setLevel(Level.SEVERE);
fileTxt = new FileHandler(LogFile.txt");
// create a TXT formatter
formatterTxt = new LogWriter();
fileTxt.setFormatter(formatterTxt);
logger.addHandler(fileTxt);
}
}
LogWriter.java
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.logging.Formatter;
import java.util.logging.Handler;
import java.util.logging.LogRecord;
class LogWriter extends Formatter {
public String format(LogRecord rec) {
System.out.println("RECORDING..............");
StringBuffer buf = new StringBuffer(1000);
buf.append(rec.getLevel());
buf.append(calcDate(rec.getMillis()));
buf.append(formatMessage(rec));
return buf.toString();
}
private String calcDate(long millisecs) {
SimpleDateFormat date_format = new SimpleDateFormat("MMM dd,yyyy HH:mm\n");
Date resultdate = new Date(millisecs);
return date_format.format(resultdate);
}
public String getHead(Handler h) {
return ("START " + new Date()) + "\n";
}
public String getTail(Handler h) {
return "END " + new Date() + "\n";
}
}
Log prints the START and END but doesn't even enter in the buff ""RECORDING.............."" so basically nothing is being logged. Any idea???

Please put include statements in your examples so others can try your code.
If you are using java.util.logging, try moving to logback. Logback logging will log properly with no configuration. If you are using java.util.logging then you'll need to find a tutorial on how to configure it, as if it's not configured it doesn't log like you would expect.

The logging framework use a configuration file, where u can set "where and what" to output, for java.util.logging the configuration file is under the folder lib of ure current jvm "/jdk1.x.x/jre/lib/logging.properties" I share my link the problem is in spanish config logging
In short words search the next line and change INFO -> ALL
java.util.logging.ConsoleHandler.level=INFO
java.util.logging.ConsoleHandler.level=ALL
In your code u only need to log message u want, ex:
public class TestLog {
private static final Logger log = Logger.getLogger(TestLog.class.getName());
public static void doLog() {
log.info("info log");
log.fine("fine log");
log.finer("finer log");
.....
log.severe("severe log");
}
}
Always try to use fine, finer or finest for ure debug message, don't use INFO because always print on default config and can slow ure application

Related

How to turn off log4j logging

I work on my Spring Boot app which uses Spring API client as a maven depencency. When I use it in my code, it logs data. How can I turn it off? Where shall I place log4j.properties to actually work? I tried inside resources and also inside folder with my service which uses it.
package com.example.demo.service;
import com.wrapper.spotify.SpotifyApi;
import com.wrapper.spotify.SpotifyHttpManager;
import com.wrapper.spotify.exceptions.SpotifyWebApiException;
import com.wrapper.spotify.model_objects.credentials.AuthorizationCodeCredentials;
import com.wrapper.spotify.requests.authorization.authorization_code.AuthorizationCodeRequest;
import org.apache.hc.core5.http.ParseException;
import java.io.IOException;
import java.net.URI;
import java.util.concurrent.CancellationException;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;
public class AuthorizationCodeExample {
private static final String clientId = "";
private static final String clientSecret = "";
private static final URI redirectUri = SpotifyHttpManager.makeUri("");
private static final String code = "";
private static final SpotifyApi spotifyApi = new SpotifyApi.Builder()
.setClientId(clientId)
.setClientSecret(clientSecret)
.setRedirectUri(redirectUri)
.build();
private static final AuthorizationCodeRequest authorizationCodeRequest = spotifyApi.authorizationCode(code)
.build();
public static void authorizationCode_Sync() {
try {
final AuthorizationCodeCredentials authorizationCodeCredentials = authorizationCodeRequest.execute();
// Set access and refresh token for further "spotifyApi" object usage
spotifyApi.setAccessToken(authorizationCodeCredentials.getAccessToken());
spotifyApi.setRefreshToken(authorizationCodeCredentials.getRefreshToken());
System.out.println("Expires in: " + authorizationCodeCredentials.getExpiresIn());
} catch (IOException | SpotifyWebApiException | ParseException e) {
System.out.println("Error: " + e.getMessage());
}
}
public static void main(String[] args) {
authorizationCode_Sync();
}
}
This is my project tree:
https://imgur.com/mS676gw
logging.level.*=LEVEL
There are different levels available, the one you are looking for is OFF. So just add the following line into your application.properties file
logging.level.*=OFF
It should be resources folder. But did you made changes inside the file to turn off logs ?
log4j.rootLogger=OFF, Note that this has the highest priority and will turn off all logging.

Linux - IO exceptions when running jar file through shell script

I am using Debain 8.0 - jessie (64 bit).
I am getting IO exceptions when I try to run a jar file, from outside its directory, through a shell script.
Directory: "/home/rscedit"
Files: "data (directory)" "run.sh (file)" "Webserver.jar (file)"
When I try to run "run.sh" from anywhere besides "/home/rscedit", I am facing IO exceptions in my jar file.
But if I try to run "run.sh" from "/home/rscedit", it runs perfectly fine.
I want to run my shell script at startup, so I should be able to run my shell script from outside "/home/rscedit" right?
Shell script
#!/bin/sh
java -jar -Xmx20480m /home/rscedit/Webserver.jar
read –n1
The error I get when executing my shell script
java.nio.file.NoSuchFileException: ./data/log/ipn.log.lck
at sun.nio.fs.UnixException.translateToIOException(UnixException.java:86)
at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:102)
at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:107)
at sun.nio.fs.UnixFileSystemProvider.newFileChannel(UnixFileSystemProvider.java:177)
at java.nio.channels.FileChannel.open(FileChannel.java:287)
at java.nio.channels.FileChannel.open(FileChannel.java:335)
at java.util.logging.FileHandler.openFiles(FileHandler.java:459)
at java.util.logging.FileHandler.<init>(FileHandler.java:326)
at org.displee.utilities.logging.LogFactory.loadFileLogger(LogFactory.java:44)
at org.displee.utilities.logging.LogFactory.<clinit>(LogFactory.java:19)
LogFactory.java
package org.displee.utilities.logging;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.*;
public class LogFactory {
private static final String FORMAT = "%1$td-%1$tm-%1$tY %1$tH:%1$tM:%1$tS %4$s %2$s - %5$s%6$s%n";
private static final Map<String, Logger> MAP = new HashMap<>();
static {
try {
loadFileLogger("ipn", "./data/log/ipn.log");
loadFileLogger("error", "./data/log/error.log");
Logger logger = Logger.getLogger("console");
logger.setUseParentHandlers(false);
ConsoleHandler ch = new ConsoleHandler();
ch.setFormatter(new ConsoleFormatter());
ch.setLevel(Level.ALL);
logger.addHandler(ch);
register(logger.getName(), logger);
} catch (IOException e) {
e.printStackTrace();
}
}
public static void register(String name, Logger logger) {
MAP.putIfAbsent(name, logger);
}
public static Logger get(String name) {
return MAP.get(name);
}
private static Logger loadFileLogger(String name, String path) throws IOException {
Logger logger = Logger.getLogger(name);
FileHandler fh = new FileHandler(path, true);
fh.setFormatter(new ConsoleFormatter());
logger.addHandler(fh);
logger.setUseParentHandlers(false);
register(name, logger);
return logger;
}
private static class ConsoleFormatter extends Formatter {
#Override
public synchronized String format(LogRecord record) {
Date date = new Date();
date.setTime(record.getMillis());
String source;
if (record.getSourceClassName() != null) {
source = record.getSourceClassName();
if (record.getSourceMethodName() != null) {
source += " " + record.getSourceMethodName();
}
} else {
source = record.getLoggerName();
}
String message = formatMessage(record);
String throwable = "";
if (record.getThrown() != null) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
pw.println();
record.getThrown().printStackTrace(pw);
pw.close();
throwable = sw.toString();
}
return String.format(FORMAT,
date,
source,
record.getLoggerName(),
"LOG",
message,
throwable);
}
}
}
The command I use to execute my shell script
exec /home/rscedit/run.sh
Edit: my data map is not only containing log files, but also other stuff like website files.
Your java program seems to be sensitive to working directory. Easiest solution I know, change this
java -jar -Xmx20480m /home/rscedit/Webserver.jar
to
(cd /home/rscedit ; java -jar -Xmx20480m Webserver.jar)
Or, change the Java, this (and everywhere you have the pattern)
loadFileLogger("ipn", "./data/log/ipn.log");
loadFileLogger("error", "./data/log/error.log");
to something like (to make it relative to $HOME),
loadFileLogger("ipn", new File(System.getProperty("user.home"),
"data/log/ipn.log").getPath());
loadFileLogger("error", new File(System.getProperty("user.home"),
"data/log/error.log").getPath());

Log4j writes to application log file instead of own log file

Log4j writes to application log file instead of my own log file.
I tried to find a solution without editing the log4j.properties. Do I have to edit the config file? Why the lg file is not been created.
The app runs as a tomcat web app.
import org.apache.log4j.Logger;
import org.apache.log4j.FileAppender;
import org.apache.log4j.Level;
import org.apache.log4j.SimpleLayout;
public class ArchiveJanitor extends SecureResource {
private static final Logger logger = org.apache.log4j.Logger.getRootLogger();
public ArchiveJanitor(Context context, Request request, Response response) {
super(context, request, response);
try {
SimpleLayout layout = new SimpleLayout();
FileAppender fileAppender = new FileAppender( layout, "logs/Janitor.log", false );
logger.addAppender(fileAppender);
logger.setLevel((Level) Level.ALL);
}catch (IOException e){
logger.error(e.toString());
}
}
public void doSmth(){
logger.error("error ....")
}
}
Instead of private static final Logger logger = org.apache.log4j.Logger.getRootLogger(); try to use public static final Logger logger = LogManager.getLogger(ArchiveJanitor.class);
But probably its better to config it all in .properties file

where to specify file name and path when logging exceptions in java?

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.

Redirect slf4j to string

How can I configure slf4j to redirect all logged information to a Java string?
This is sometimes useful in unit tests, e.g. to test no warnings are printed when loading a servlet, or to make sure a forbidden SQL table is never used.
A bit late, but still...
As logging configurations should be easy to replace when unit testing, you could just configure to log over stdout and then capture that prior to executing the logging subject.
Then set the logger to be silent for all but the subject under test.
#Test
public void test()
{
String log = captureStdOut(() -> {
// ... invoke method that shouldn't log
});
assertThat(log, is(emptyString()));
}
public static String captureStdOut(Runnable r)
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintStream out = System.out;
try {
System.setOut(new PrintStream(baos, true, StandardCharsets.UTF_8.name()));
r.run();
return new String(baos.toByteArray(), StandardCharsets.UTF_8);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("End of the world, Java doesn't recognise UTF-8");
} finally {
System.setOut(out);
}
}
And if using slf4j over log4j in tests, a simple log4j.properties:
log4j.rootLogger=OFF, out
log4j.category.com.acme.YourServlet=INFO, out
log4j.appender.out=org.apache.log4j.ConsoleAppender
log4j.appender.out.layout=org.apache.log4j.PatternLayout
log4j.appender.out.layout.ConversionPattern=%-5p %c{1}:%L - %m%n
Or if you loath configuration as an external dependencies in unit tests, then programmatically configure log4j:
//...
static final String CONSOLE_APPENDER_NAME = "console.appender";
private String pattern = "%d [%p|%c|%C{1}] %m%n";
private Level threshold = Level.ALL;
private Level defaultLevel = Level.OFF;
//...
public void configure()
{
configureRootLogger();
configureConsoleAppender();
configureCustomLevels();
}
private void configureConsoleAppender()
{
ConsoleAppender console = new ConsoleAppender();
console.setName(CONSOLE_APPENDER_NAME);
console.setLayout(new PatternLayout(pattern));
console.setThreshold(threshold);
console.activateOptions();
Logger.getRootLogger().addAppender(console);
}
private void configureRootLogger()
{
Logger.getRootLogger().getLoggerRepository().resetConfiguration();
Logger.getRootLogger().setLevel(defaultLevel);
}
As I see it you have two options.
First you could implement a custom Appender (depending on which slf4j implementation you're using) which simply appends each logged statement to a StringBuffer. In this case you probably have to hold a static reference to your StringBuffer so your test classes can access it.
Second you could write your own implementation of ILoggerFactory and Logger. Again your Logger would just append all the messages to internal StringBuffers, although in this case you'd probably have multiple buffers, one for each log level. If you did it this way you'd have an easy way of retrieving the Logger instances since you'd own the factory that was distributing them.
Shouldn't make sense to redirect all the logs to watch to a separate log file? That way you have the control you want (you can delete the log file before running the test and checking if the file has been create at any moment) without losing the benefits of logging (redirecting your output to a String can cause memory leaks and is less performant)
This is a simple way to log to the console:
import org.slf4j.LoggerFactory;
import ch.qos.logback.classic.BasicConfigurator;
import ch.qos.logback.classic.LoggerContext;
private void LogToConsole() {
BasicConfigurator bc = new BasicConfigurator();
LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
lc.reset();
bc.configure(lc);
}
Not quite exactly what you're doing, but I've written a LogInterceptingTestHarness which enables assertion of specific log statements. You could similarly use it (or something like it) to assert nothing has been logged at a certain level.
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import java.util.List;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.Appender;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.Logger;
import org.junit.After;
import org.junit.Before;
import org.mockito.ArgumentCaptor;
import lombok.Getter;
/**
* Use this class to intercept logs for the purposes of unit testing log output.
* <p>
* On {#link Before} of the unit test, call {#link #initHarness(Class, Level)} or {#link #initHarness(Class, Level, String)} to get a new harness and hold onto reference to it in a class-level
* variable of your unit test
* <p>
* On {#link After} of the unit test, you MUST call {#link #teardown()} in order to remove the mocked {#link #appender}
*
* #author jeff.nelson
*
*/
#Getter
public class LogInterceptingTestHarness {
private final Appender appender;
private final ArgumentCaptor<LogEvent> logEventCaptor;
private final Logger itsLogger;
private LogInterceptingTestHarness(Class<?> classInterceptLogsFor, Level logLevel, String appenderName) {
logEventCaptor = ArgumentCaptor.forClass(LogEvent.class);
appender = mock(Appender.class);
doReturn("testAppender").when(appender).getName();
doReturn(true).when(appender).isStarted();
itsLogger = (Logger) LogManager.getLogger(classInterceptLogsFor);
itsLogger.addAppender(appender);
itsLogger.setLevel(logLevel);
}
public void teardown() {
itsLogger.removeAppender(appender);
}
public List<LogEvent> verifyNumLogEvents(int numEvents) {
verify(appender, times(numEvents)).append(logEventCaptor.capture());
return logEventCaptor.getAllValues();
}
public LogEvent verifyOneLogEvent() {
return verifyNumLogEvents(1).get(0);
}
public void assertLoggedMessage(String message) {
assertLogMessage(message, logEventCaptor.getValue());
}
public void assertLoggedMessage(String message, int messageIndex) {
assertLogMessage(message, logEventCaptor.getAllValues().get(messageIndex));
}
public static void assertLogMessage(String message, LogEvent event) {
assertEquals(message, event.getMessage().getFormattedMessage());
}
public static LogInterceptingTestHarness initHarness(Class<?> classInterceptLogsFor, Level logLevel) {
return initHarness(classInterceptLogsFor, logLevel, "testAppender");
}
public static LogInterceptingTestHarness initHarness(Class<?> classInterceptLogsFor, Level logLevel, String appenderName) {
return new LogInterceptingTestHarness(classInterceptLogsFor, logLevel, appenderName);
}
}

Categories

Resources