Can Jetty capture System.out and System.err to a log file? - java

I am working with Jetty embedded server, building a REST api out of a legacy jar, which has a lot of critically useful calls to println (I run its classes and it prints stuff in console). I am trying now to have these printlns in a file, along with the requests status, but the NCSARequestLog only logs in the file date and code of the responses. Is there a way to log everything in a file then? I'm pretty sure it is possible because before we were wrapping the legacy jar in a war file deployed into Glassfish, and all prints used to show up in the server log.
Thanks

In the jetty-util-<ver>.jar there is a class called RolloverFileOutputStream which can be instantiated and then set to take over the roll of System.out and System.err
An example of this:
package demo;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.util.TimeZone;
import org.eclipse.jetty.util.RolloverFileOutputStream;
public class ConsoleCaptureDemo
{
public static void main(String[] args) throws IOException
{
File loggingDir = new File("logs");
if (!loggingDir.exists())
{
if (!loggingDir.mkdirs())
{
throw new RuntimeException("Unable to create directory: " + loggingDir);
}
}
String loggingFile = new File(loggingDir, "yyyy_mm_dd.jetty.log").getAbsolutePath();
boolean append = false;
int retainDays = 90;
TimeZone zone = TimeZone.getTimeZone("GMT");
RolloverFileOutputStream logStream = new RolloverFileOutputStream(loggingFile,
append, retainDays, zone);
System.out.println("Look at " + logStream.getFilename());
PrintStream logWriter = new PrintStream(logStream);
System.setOut(logWriter);
System.setErr(logWriter);
System.out.println("From System.out - hi there");
System.err.println("From System.err - hello again");
}
}

Related

Trying to run a server with multiple clients where the client will tell me the date but my java.util.Date is not importing correctly

Hi I am currently doing a project where I have multiple clients telling the server a date however my java.util.date is not working and running me back an error message.
How would I fix this issue code is provided below as well as the message. I must also add I am writing said project in java and using the eclipse IDE.
package clientServer;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;
public class Server {
public static void main(String[] args) throws IOException {
try (ServerSocket listener = new ServerSocket(7000)) {
System.out.println("The date server is running...");
while (true) {
try (Socket socket = listener.accept()) {
PrintWriter out =
new PrintWriter(socket.getOutputStream(), true);
out.println(new Date().toString());
}
}
}
}
}
the 2 errors
for import java.util.Date it says import java.util.Date cannot be resolved
and for the code out.println(new Date()) it says Date cannot be resolved into a type
I have tried cleaning the project and using alt 5 to give it a direct path however this has not worked

Java Creating copy of file before uploading to AWS cloud

I have an image in a directory.
I want to make a copy of that image with a different name without doing harm to the original image in the same directory.
So there will be two same images in one folder with a different name.
I want a basic code like I tried -
File source = new File("resources/"+getImage(0));
File dest = new File("resources/");
source.renameTo("resources/"+getImage(0)+);
try {
FileUtils.copyDirectory(source, dest);
} catch (IOException e) {
e.printStackTrace();
}
When I upload the same image to the Amazon server multiple times in automation and then it starts giving issue to upload.
So we want to upload a mirror copy of image everytime.
In eclipse generally have resources folder. I want to make copy of a original image every-time before we upload and delete it after upload.
Kindly suggest some approach
You can just copy the file and use StandardCopyOption.COPY_ATTRIBUTES
public static final StandardCopyOption COPY_ATTRIBUTES
Copy attributes to the new file.
Files.copy(Paths.get(//path//to//file//and//filename),
Paths.get(//path//to//file//and//newfilename), StandardCopyOption.COPY_ATTRIBUTES);
Not a perfect solution, but Instead of handling pop-up box we can directly force file path into the form: [I have used date-stamp for creating new filenames but some different logic could also be used viz- Random String appender etc.]
import org.junit.jupiter.api.Test;
import java.io.*;
import java.nio.file.Files;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class Upload {
private static final String SRC_RESOURCES_FILE_PATH = System.getProperty("user.dir")+"/src/resources/";
File s1 = new File(SRC_RESOURCES_FILE_PATH+"Img1.png");
File s2 = new File(SRC_RESOURCES_FILE_PATH+"Img"+getDateStamp()+".png");
#Test
public void uploadFunction() throws IOException {
copyFileUsingJava7Files(s1,s2);
}
private String getDateStamp(){
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
Date date = new Date();
return dateFormat.format(date).toString();
}
private static void copyFileUsingJava7Files(File source, File dest)
throws IOException {
Files.copy(source.toPath(), dest.toPath());
}
}

Get file time before downloading the file using FTP

Any way to get the file creation date or last modification date without using getModificationTime in Java.
I'm using org.apache.commons.net.ftp.FTPClient class. My issue is, I'm unable to use getModificationTime to get the time stamp before downloading the file..
You can use Apache Commons Net library, here is a sample code:
package com.grebski.ftp;
import org.apache.commons.net.ftp.FTPClient;
import java.io.IOException;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Arrays;
public class FtpTest {
public static void main(String[] args) throws IOException {
String ftpUrl = "speedtest.tele2.net";
FTPClient ftpClient = new FTPClient();
ftpClient.connect(ftpUrl);
ftpClient.user("anonymous");
ftpClient.pass("anonymous#a.com");
Arrays.stream(ftpClient.listFiles()).forEach(file -> {
LocalDateTime creationDateTime = Instant.ofEpochMilli(file.getTimestamp().getTimeInMillis()).atZone(ZoneId.systemDefault()).toLocalDateTime();
String msg = String.format("%s %s", file.getName(), creationDateTime);
System.out.println(msg);
}
);
}
}
Did you get a chance to find the size of the file and the network speed? They are important aspects to learn the download time.

How to get the Java default logger output to a file?

I know how to create log messages in Java that appear in the console:
java.util.logging.Logger.getLogger(<CLASSNAME>.class.getName())
.log(Level.INFO, "LOG MESSAGE");
However, I am currently working on a web app (in netbeans IDE). In a web app, it is unfortunately not possible to have the logger output to the console.
Hence, I want to direct output to a file.
A few things I tried, didn't work. For example, I tried the following:
How to write logs in text file when using java.util.logging.Logger
https://examples.javacodegeeks.com/core-java/util/logging/java-util-logging-example/
...and many others, but nothing seems to work.
How can it be so difficult to direct output to a text file? Does anybody know how to do a direct output of the java default logger to a file?
Try this. It will create a text file in project folder.
Please make sure to do a refresh to see the file.
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.logging.FileHandler;
import java.util.logging.Handler;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;
public class Test {
static Handler fileHandler = null;
private static final Logger LOGGER = Logger.getLogger(Test.class
.getClass().getName());
public static void setup() {
try {
fileHandler = new FileHandler("./logfile.log");//file
SimpleFormatter simple = new SimpleFormatter();
fileHandler.setFormatter(simple);
LOGGER.addHandler(fileHandler);//adding Handler for file
} catch (IOException e) {
// TODO Auto-generated catch block
}
}
public static void main(String[] args) {
setup();//calling to the file content
LOGGER.info("------------------START--------------------");
//here the Information or Contents that in file
}
}
I want to be able to do in my Java Netbeans application the same thing as in a normal application: writing print statements to the console or some file for debugging purposes.
I tested this with Netbeans creating a brand new web project running Tomcat 8 with new servlet. I modified the servlet to include:
Logger.getLogger("foo").info("This is a test message.");
And the result is printed to the Tomcat console by default with no changes to Tomcat, no changes to the project, and no logger.properties in the project.
In a web app, it is unfortunately not possible to have the logger output to the console.
You should have multiple tabs at the bottom of Netbeans. One is the console output from the Netbeans ANT task that runs the compiler and launches Tomcat. You should then have another tab that is the output from the Tomcat instance. Under that tab, you should see the logger messages. The logging in Tomcat points out that System.err/out are remapped to files:
When running Tomcat on unixes, the console output is usually redirected to the file named catalina.out. When running as a service on Windows, the console output is also caught and redirected, but the file names are different.
Default locations are in the Tomcat or domain home under a folder called logs. The default configuration should already be writing logger output to a file because of the installed console handler and System.err being remapped to a file. It just may not be the location you want.
Even though System.err/out are remapped you can write to the JVM console by creating your own custom handler that writes to a java.io.FileDescriptor.
import java.io.FileDescriptor;
import java.io.FileOutputStream;
import java.util.logging.LogRecord;
import java.util.logging.SimpleFormatter;
import java.util.logging.StreamHandler;
public class FileDescriptorHandler extends StreamHandler {
public FileDescriptorHandler() {
super(new FileOutputStream(FileDescriptor.out), new SimpleFormatter());
}
#Override
public synchronized void publish(LogRecord record) {
super.publish(record);
super.flush();
}
#Override
public void close() {
flush();
}
}
By default Netbeans will capture and display this console output. Same is true if you just write code that prints to the console.
How can it be so difficult to direct output to a text file?
Does anybody know how to do direct output of the java default logger to a file?
This is also covered in the Tomcat documentation:
Example logging.properties for the servlet-examples web application to be placed in WEB-INF/classes inside the web application:
handlers = org.apache.juli.FileHandler, java.util.logging.ConsoleHandler
.handlers = org.apache.juli.FileHandler, java.util.logging.ConsoleHandler
############################################################
# Handler specific properties.
# Describes specific configuration info for Handlers.
############################################################
org.apache.juli.FileHandler.level = FINE
org.apache.juli.FileHandler.directory = ${catalina.base}/logs
org.apache.juli.FileHandler.prefix = ${classloader.webappName}.
java.util.logging.ConsoleHandler.level = FINE
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
Be aware that for Tomcat you have to declare the handlers that can be used unlike the standard LogManager.
If you can't get the log configuration files working then add a servlet context listener to your project and manually install the file handler.
import java.io.IOException;
import java.util.logging.FileHandler;
import java.util.logging.Handler;
import java.util.logging.Logger;
import javax.servlet.ServletContextEvent;
import javax.servlet.annotation.WebListener;
import javax.servlet.ServletContextListener;
#WebListener
public class HandlerInstaller implements ServletContextListener {
private static final Logger logger = Logger.getLogger("");
private Handler target;
#Override
public synchronized void contextInitialized(ServletContextEvent sce) {
try {
target = new FileHandler();
logger.addHandler(target);
} catch (IOException | RuntimeException ex) {
sce.getServletContext().log(sce.toString(), ex);
}
}
#Override
public synchronized void contextDestroyed(ServletContextEvent sce) {
logger.removeHandler(target);
target.close();
target = null;
}
}
You should strongly consider using java.nio.file.Path;
This works for me; Put the file wherever you want !
final Logger LOGGER = Logger.getLogger(logIntextfile.class
.getClass().getName());
public void WriteToLog() {
Path path = Paths.get("c:", "myFiles", "logfile.log");
try {
FileHandler file = new FileHandler(path.toString());
SimpleFormatter simple = new SimpleFormatter();
file.setFormatter(simple);
LOGGER.addHandler(file);
} catch (IOException e) {
System.err.println ("Try another day");
}
This also work on mac os
Path path = Paths.get("/Users/",System.getProperty("user.name"),"myFiles", "logfile.log");
You can provide your own logging file on the classpath of your project directory
Netbeans logging : http://bits.netbeans.org/dev/javadoc/org-openide-util/org/openide/util/doc-files/logging.html
Java Util logging with logging properties file sample : http://www.javapractices.com/topic/TopicAction.do?Id=143

Folder monitor Java code prints report twice

Using some answers from this site I created a small Folder Monitor app in Java. It is supposed to check for changes to a specific folder and output those changes to a text file. Unfortunately it prints the report twice for every change. The problem is I cannot figure out where the first line of the report comes from. Please help me understand what am I doing wrong.
Please find the code below. I removed part of the code as it does not affect the Q&A.
import java.io.File;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.apache.commons.io.monitor.FileAlterationListener;
import org.apache.commons.io.monitor.FileAlterationListenerAdaptor;
import org.apache.commons.io.monitor.FileAlterationMonitor;
import org.apache.commons.io.monitor.FileAlterationObserver;
public class FolderMonitor {
public FolderMonitor() {}
//path to a folder you are monitoring
public static final String FOLDER = "D:\\WatchedDir";
public static void main(String[] args) throws Exception
{
System.out.println("monitoring started");
// The monitor will perform polling on the folder every 5 seconds
final long pollingInterval = 6 * 1000;
// Let's get a directory as a File object and sort all its files.
File folderToMonitor = new File(FOLDER);
File outputFile = new File("H:\\Dir_changes.txt");
if (!folderToMonitor.exists())
{
// Test to see if monitored folder exists
throw new RuntimeException("Directory not found: " + FOLDER);
}
FileAlterationObserver observer = new FileAlterationObserver(folderToMonitor);
FileAlterationMonitor monitor = new FileAlterationMonitor(pollingInterval);
FileAlterationListener listener = new FileAlterationListenerAdaptor()
{
// Is triggered when a file in the monitored folder is modified from
#Override
public void onFileChange(File file)
{
// "file" is the reference to the newly created file
try {writeToFile(outputFile, convertLongToDate(outputFile.lastModified()), ("File modified: "+ file.getCanonicalPath()));}
catch (IOException e) {e.printStackTrace();}
}
};
observer.addListener(listener);
monitor.addObserver(observer);
monitor.start();
}
private static void writeToFile(File filePath, String timeStamp, String caughtChange) throws IOException
{
FileWriter fileWriter = new FileWriter(filePath,true);
BufferedWriter bufferFileWriter = new BufferedWriter(fileWriter);
fileWriter.append("\r" + timeStamp + " - " + caughtChange + "\r");
bufferFileWriter.close();
}
private static String convertLongToDate(long input)
{
Date date = new Date(input);
Calendar cal = new GregorianCalendar();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MMM/dd hh:mm:ss z");
sdf.setCalendar(cal);
cal.setTime(date);
return sdf.format(date);
}
}
The output looks like this:
1454622374878 File modified: D:\WatchedDir\second\inside3.txt
2016/Feb/04 04:46:25 EST - File modified: D:\WatchedDir\second\inside3.txt
I can not figure out where the highlighted (bold) part comes from and how to get rid of it. Please help!
I ran the same code that you posted and don't see the extra output in the .txt file. can you please try it by directing the output to a new file and see if it makes any difference
For some reason Eclipse was executing code that I have already removed from the class and saved the changes.
After I have restarted Eclipse and executed the code again, everything was running fine (surprise).
I considered deleting this post but I decided to leave it just in case someone will be looking for such a piece of code. I will leave it to the moderators to decide if this question should be deleted.

Categories