I have MyLogger class which contains:
public class MyLogger {
private final static Logger logger = Logger.getLogger(MyLogger.class.getName());
private static FileHandler fileHandler;
private static String loggerFileName;
public MyLogger() {
}
public static void createMyLogger(String filename){
loggerFileName = filename;
try {
File loggerFile = new File(filename);
boolean fileExists = loggerFile.exists();
if(fileExists){
loggerFile.delete();
File lockFile = new File(filename+".lck");
if(lockFile.exists())
lockFile.delete();
}
fileHandler = new FileHandler(filename,true);
} catch (IOException e) {
e.printStackTrace();
}
logger.addHandler(fileHandler);
SimpleFormatter simpleFormatter = new SimpleFormatter();
fileHandler.setFormatter(simpleFormatter);
}
public static void log(String msg) {
logger.log(Level.INFO, msg);
}
public static void log(Exception ex) {
logger.log(Level.SEVERE, "Exception",ex);
}
public static String getLoggerFileName() {
return loggerFileName;
}
public static void setLoggerFileName(String loggerFileName) {
MyLogger.loggerFileName = loggerFileName;
}
And I am having my further execution in threads, i.e. When I am starting first process then Logger File is created and logs are recorded, but when I starts another process then again different thread is created and also new logger file is created but because of static methods and reference It mixed up the both process logs in both logger files...
When I start process for every thread following method is called:
public void start(String process) {
try{
String filename = process.replace(".com", "");
MyLogger.createXPathLogger(filename.concat(WordUtils.capitalize(type))+ ".log");
MyLogger.log("got parameters ===>> process : "+process);
}catch (Exception e) {
MyLogger.log("Exception In main() method....");
MyLogger.log("*****"+process+" process failed In main() method.*****");
MyLogger.log(e);
}
}
So what can I do for this, Ho can I do thread safe logging?
thanks in advance..
The idea here won't really work. One logger gets created and you add the each handler to the logger.
What you really need is a concept of a log context. You need to isolate the creation of the logger on a per-thread basis which AFAIK you can't do with J.U.L.
This is a very rough around the edges example of using JBoss Log Manager to do this:
import java.io.File;
import java.io.IOException;
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;
import org.jboss.logmanager.LogContext;
public class MyLogger {
private static final ThreadLocal<MyLogger> LOCAL_LOGGER = new ThreadLocal<MyLogger>();
private final Logger logger;
private MyLogger(final Logger logger) {
this.logger = logger;
}
public static MyLogger createMyLogger(final String filename) {
MyLogger result = LOCAL_LOGGER.get();
if (result == null) {
final LogContext logContext = LogContext.create();
final Logger logger = logContext.getLogger(MyLogger.class.getName());
final FileHandler fileHandler;
try {
final File loggerFile = new File(filename);
if (loggerFile.exists()) {
loggerFile.delete();
File lockFile = new File(filename + ".lck");
if (lockFile.exists())
lockFile.delete();
}
fileHandler = new FileHandler(filename, true);
} catch (IOException e) {
throw new RuntimeException("Could not create file handler", e);
}
logger.addHandler(fileHandler);
fileHandler.setFormatter(new SimpleFormatter());
final MyLogger myLogger = new MyLogger(logger);
LOCAL_LOGGER.set(myLogger);
result = myLogger;
}
return result;
}
public void log(String msg) {
logger.log(Level.INFO, msg);
}
public void log(Exception ex) {
logger.log(Level.SEVERE, "Exception", ex);
}
}
Related
I am trying to read dat from kafka topic and writing it to HDFS filesystem, I buid my project using the apex malhar from [ https://github.com/apache/apex-malhar/tree/master/examples/kafka].
Unfortunally, after setting up the kafka properties and hadoop config the data are not created in my hdfs 2.6.0 system.
PS: the console dosen't show any error and everything seems to work fine
here the code I am using for my app
public class TestConsumer {
public static void main(String[] args) {
Consumer consumerThread = new Consumer(KafkaProperties.TOPIC);
consumerThread.start();
ApplicationTest a = new ApplicationTest();
try {
a.testApplication();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Here the ApplicationTest class example from apex malhar
package org.apache.apex.examples.kafka.kafka2hdfs;
import org.apache.log4j.Logger;
import javax.validation.ConstraintViolationException;
import org.junit.Rule;
import org.apache.apex.malhar.kafka.AbstractKafkaInputOperator;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.net.NetUtils;
import com.datatorrent.api.LocalMode;
import info.batey.kafka.unit.KafkaUnitRule;
/**
* Test the DAG declaration in local mode.
*/
public class ApplicationTest
{
private static final Logger LOG = Logger.getLogger(ApplicationTest.class);
private static final String TOPIC = "kafka2hdfs";
private static final int zkPort = NetUtils.getFreeSocketPort();
private static final int brokerPort = NetUtils.getFreeSocketPort();
private static final String BROKER = "localhost:" + brokerPort;
private static final String FILE_NAME = "test";
private static final String FILE_DIR = "./target/tmp/FromKafka";
// broker port must match properties.xml
#Rule
private static KafkaUnitRule kafkaUnitRule = new KafkaUnitRule(zkPort, brokerPort);
public void testApplication() throws Exception
{
try {
// run app asynchronously; terminate after results are checked
LocalMode.Controller lc = asyncRun();
lc.shutdown();
} catch (ConstraintViolationException e) {
LOG.error("constraint violations: " + e.getConstraintViolations());
}
}
private Configuration getConfig()
{
Configuration conf = new Configuration(false);
String pre = "dt.operator.kafkaIn.prop.";
conf.setEnum(pre + "initialOffset", AbstractKafkaInputOperator.InitialOffset.EARLIEST);
conf.setInt(pre + "initialPartitionCount", 1);
conf.set(pre + "topics", TOPIC);
conf.set(pre + "clusters", BROKER);
pre = "dt.operator.fileOut.prop.";
conf.set(pre + "filePath", FILE_DIR);
conf.set(pre + "baseName", FILE_NAME);
conf.setInt(pre + "maxLength", 40);
conf.setInt(pre + "rotationWindows", 3);
return conf;
}
private LocalMode.Controller asyncRun() throws Exception
{
Configuration conf = getConfig();
LocalMode lma = LocalMode.newInstance();
lma.prepareDAG(new KafkaApp(), conf);
LocalMode.Controller lc = lma.getController();
lc.runAsync();
return lc;
}
}
After runAsync and before shutdown, you would need to wait for the expected results (otherwise the DAG will exit immediately). That's actually what happens in the example.
I want to add exceptions in a single log file, In my source code following code is used multiple times... i want to store all exceptions in single file, but it creates multiple files like exception.log, exception.log.1, exception.log.1.lck, exception.log.2 and so on...
Date dir1 = new java.util.Date(System.currentTimeMillis());
String baseDir1 = "/home/gaurav/usr/logs/ESBegin/";
String newDir1 = createDateBasedDirectory(baseDir1, dir1);
System.out.println("Exception :: " + e.getMessage());
Logger logger = Logger.getLogger("MyLog");
FileHandler fh;
try {
// This block configure the logger with handler and formatter
fh = new FileHandler(newDir1+"/exception.log");
logger.addHandler(fh);
SimpleFormatter formatter = new SimpleFormatter();
fh.setFormatter(formatter);
// the following statement is used to log any messages
logger.info(e.getMessage());
} catch (SecurityException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
It's because you create a new FileHandler each time you call that method, instead make it a class instance variable. I tested it and it works:
import java.io.IOException;
import java.util.Date;
import java.util.logging.FileHandler;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;
public class Main {
private static String newDir1 = "C:\\Users\\pavel.orekhov\\Desktop";
private static FileHandler fh;
static {
try {
fh = new FileHandler(newDir1 + "\\exception.log", 0, 1, true);
} catch (IOException | SecurityException e) {
}
}
static void test() {
Date dir1 = new java.util.Date(System.currentTimeMillis());
Logger logger = Logger.getLogger("MyLog");
logger.addHandler(fh);
SimpleFormatter formatter = new SimpleFormatter();
fh.setFormatter(formatter);
logger.info("test");
}
public static void main(String[] args) {
// all these write to the same file
test();
test();
test();
test();
}
}
The code that you had was something like this:
import java.io.IOException;
import java.util.Date;
import java.util.logging.FileHandler;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;
public class Main {
static void test() {
Date dir1 = new java.util.Date(System.currentTimeMillis());
String newDir1 = "C:\\Users\\pavel.orekhov\\Desktop";
Logger logger = Logger.getLogger("MyLog");
FileHandler fh;
try {
fh = new FileHandler(newDir1 + "\\exception.log", 0, 1, true);
logger.addHandler(fh);
SimpleFormatter formatter = new SimpleFormatter();
fh.setFormatter(formatter);
logger.info("test");
} catch (SecurityException | IOException ex) {
ex.printStackTrace();
}
}
public static void main(String[] args) {
test(); // creates file 1
test(); // creates file 2
test(); // creates file 3
test(); // creates file 4
}
}
this does create as many files as you have calls to the test() method.
I'm pretty new in Java but I have to write a simple logger.
My problem is that my logger won't transfer its handler.
My first class is:
public class LoggerClass {
static final Logger logger = Logger.getLogger("myLogger");
FileHandler fh;
public LoggerClass() {
try {
this.fh = new FileHandler("C:/Users/Administrator/Desktop/Logging%u.txt");
} catch (IOException | SecurityException ex) {
Logger.getLogger(LoggerClass.class.getName()).log(Level.SEVERE, null, ex);
}
logger.addHandler(fh);
SimpleFormatter formatter = new SimpleFormatter();
fh.setFormatter(formatter);
}
}
and i want to transfer the logger to another class by doing this:
package Logger;
import static Logger.LoggerClass.logger;
import java.io.IOException;
import java.util.logging.Level;
public class LoggingTest {
public static void main(String[] args) throws IOException {
try
{
((Object) null).toString();
}
catch ( Exception e )
{
logger.log( Level.SEVERE, "oh oh", e );
}
logger.info( "Hat funktioniert" );
}
}
i tried nearly everything that i've found, and the logger functions but it only gives its output on console and not how it should be in a file
In your test you never configured your logger. Try this:
package Logger;
import static Logger.LoggerClass.logger;
import java.io.IOException;
import java.util.logging.Level;
//There are better ways to do this.
static {
new LoggerClass();
}
public class LoggingTest {
public static void main(String[] args) throws IOException {
try
{
((Object) null).toString();
}
catch ( Exception e )
{
logger.log( Level.SEVERE, "oh oh", e );
}
logger.info( "Hat funktioniert" );
}
}
change this:
static final Logger logger = Logger.getLogger("myLogger");
To
public static final Logger logger = Logger.getLogger("myLogger");
Reason you have given it a default access in your class where you defined Logger and using defail access you can access it in package only. While where you are using is you have another package and hence error.
Apart form above use logger like:
LoggerInterface.logger.info( "Hat funktioniert" );
Since you defined it static so use classname.instance.method(parameter)
I'm using an IntentService to append single NMEA strings to a log file stored in the external public storage on an Android device, but I'm getting inconsistent behavior.
First off the log file does not appear when the device is connected for USB debugging. I read that many Android devices cannot write to external storage when connected via USB, but even when it is run disconnected from USB, it may take several times of turning it on and off and rerunning the applications before the log file appears in the file system. If I do not clear the log, I still have to restart the phone before it will begin appending to the file again.
How can I get the file to appear consistently everytime?
import android.app.IntentService;
import android.content.Intent;
public class LogFileService extends IntentService {
DebugLog debug = new DebugLog("LogFileService");
public static final String GPS_STR = "GPS_STR";
public static final String FILE_PATH = "FILE_PATH";
public static final String FILE_NAME = "gps_data.txt";
public LogFileService() {
super("LogFileService");
}
#Override
protected void onHandleIntent(Intent intent) {
debug.log("Handling intent");
String data = intent.getStringExtra(GPS_STR);
debug.log("Writing " + data);
GpsLogFile logFile = new GpsLogFile(FILE_NAME);
logFile.open();
logFile.write(data);
logFile.close();
}
#Override
public void onCreate() {
super.onCreate();
debug.log("Created");
}
}
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import android.content.Context;
import android.os.Environment;
public class GpsLogFile {
DebugLog debug = new DebugLog("LogFile");
private File filePath = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DOWNLOADS
);
private File logFile = null;
private String fileName = null;
private PrintWriter fileOut = null;
public GpsLogFile(String name) {
fileName = name;
}
public void open() {
try {
filePath.mkdirs();
if (!isExternalMediaAvailable()) {
throw new IOException("External media not available.");
}
logFile = new File(filePath, fileName);
//logFile.mkdirs();
if (!logFile.exists()) {
logFile.createNewFile();
}
fileOut = new PrintWriter(
new FileOutputStream(logFile.getAbsolutePath(), true)
);
} catch (IOException e) {
debug.log("Unable to open file.");
debug.log(e.getMessage());
}
}
public void write(String data) {
debug.log("Writing to " + logFile.getAbsolutePath() + " " + data);
try {
fileOut.write(data);
//fileOut.newLine();
checkPrintWriterError(fileOut);
fileOut.flush();
} catch (IOException e) {
debug.log("Unable to write");
debug.log(e.getMessage());
}
}
public void close() {
if (null != fileOut) {
try {
fileOut.close();
checkPrintWriterError(fileOut);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private void checkPrintWriterError(PrintWriter writer) throws IOException {
if (true == writer.checkError()) {
throw new IOException("Print writer error.");
}
}
}
i am trying to read values from properties file and
when i tried to run this program
its giving the output as
null
import java.io.FileInputStream;
import java.util.Properties;
public class JavaApplication1 {
final private static String osName = System.getProperty("os.name");
static final Properties configFile = new Properties() {
{
try {
configFile.load(new FileInputStream("config.properties"));
} catch (Exception e) {
}
}
};
private static String DIR = osName.equals("Linux") ? configFile.getProperty("tempDirForLinux") : configFile.getProperty("tempDirForWindows");
public static void main(String[] args) {
System.out.println(DIR);
}
}
The part that is a bit odd in your example is where you create an anonymous Properties class and then load the properties into that same class in an initialization statement. I'm not sure how that is meant to work (and I'm guessing doesn't)
This is probably what you want rather
public class JavaApplication1 {
final private static String osName = System.getProperty("os.name");
static final Properties configFile = new Properties();
static {
try {
configFile.load(new FileInputStream("config.properties"));
} catch (Exception e) {
e.printStackTrace();
}
};
private static String DIR = osName.equals("Linux") ? configFile.getProperty("tempDirForLinux") : configFile.getProperty("tempDirForWindows");
public static void main(String[] args) throws IOException {
System.out.println(DIR);
}
}