Our Products:   CompleteFTP  edtFTPnet/Free  edtFTPnet/PRO  edtFTPj/Free  edtFTPj/PRO
0 votes
15.3k views
in Java FTP by (600 points)
Using the logging api included in 1.1.0, how do you control log output at the object level?

In otherwords, in a single JVM I will have multiple instances of SSLFTPClient and FTPClient objects. I am using Level.DEBUG, because that gives the desired output. In addition, I will setup a unique FileAppender for each SSLFTPClient/FTPClient object, and I need the output of each to go to the appropriate log file.

From the looks of the API, it appears that everything is at a class level and not an object level. Is this the case?

As you can well imagine, a single log file with the output from even several concurrent FTP sessions is a nightmare to trace through.

Thanks,
Steve

13 Answers

0 votes
by (162k points)
A tricky question! The logging API is modelled on log4j (so that integration is possible). Logger objects in log4j are typically constructed on a class basis, not an object basis - having separate loggers per object would be difficult to configure, e.g. how would you distinguish between different instances in a configuration file so they have different destinations?

Are the (SSL)FTPClient objects running in different threads? One possibility would be for us to add the thread name as part of the output, which would easily allow you to distinguish between objects. We are currently working on 1.1.1 - some minor fixes and enhancements (e.g. a StandardOutputAppender) - and this could be added. All purchasers of edtFTPj/SSL are entitled to free upgrades as part of support for 12 months.


Using the logging api included in 1.1.0, how do you control log output at the object level?

In otherwords, in a single JVM I will have multiple instances of SSLFTPClient and FTPClient objects. I am using Level.DEBUG, because that gives the desired output. In addition, I will setup a unique FileAppender for each SSLFTPClient/FTPClient object, and I need the output of each to go to the appropriate log file.

From the looks of the API, it appears that everything is at a class level and not an object level. Is this the case?

As you can well imagine, a single log file with the output from even several concurrent FTP sessions is a nightmare to trace through.

Thanks,
Steve
0 votes
by (600 points)
Here's the rest of the problem. The different objects that I mentioned are in fact created through HTTP requests to a servlet. The servlet then makes an FTPS request. When I service an HTTP request, I need to return to the client the debug (log trace) for the FTPS session.

In my particular situation, each HTTP client request constructs its own unique file which would contain the FTPS session information. So, I already have uniqueness and separation at my level. It's really a matter of getting the FTPS session information into the log for a specific session.

I know the Apache folks dismiss separating log files on an object basis as not necessary. However, that premise is flawed in this situation because the log/debug info for a session (object) really needs to get back to a specific client.

Anything we can do here would be appreciated. We just completed the purchase of site developer license and runtime license. Not being able to separate the info at the client level means a lot of troubleshooting and debugging at the web server level. It also means that client configuration issues have to wait to be solved until the logs at the web server level can be distilled appropriately.

Thanks,
Steve



[quote="support2"]A tricky question! The logging API is modelled on log4j (so that integration is possible). Logger objects in log4j are typically constructed on a class basis, not an object basis - having separate loggers per object would be difficult to configure, e.g. how would you distinguish between different instances in a configuration file so they have different destinations?

Are the (SSL)FTPClient objects running in different threads? One possibility would be for us to add the thread name as part of the output, which would easily allow you to distinguish between objects. We are currently working on 1.1.1 - some minor fixes and enhancements (e.g. a StandardOutputAppender) - and this could be added. All purchasers of edtFTPj/SSL are entitled to free upgrades as part of support for 12 months.


[quote="reichesf"]Using the logging api included in 1.1.0, how do you control log output at the object level?

In otherwords, in a single JVM I will have multiple instances of SSLFTPClient and FTPClient objects. I am using Level.DEBUG, because that gives the desired output. In addition, I will setup a unique FileAppender for each SSLFTPClient/FTPClient object, and I need the output of each to go to the appropriate log file.

From the looks of the API, it appears that everything is at a class level and not an object level. Is this the case?

As you can well imagine, a single log file with the output from even several concurrent FTP sessions is a nightmare to trace through.

Thanks,
Steve[/quote][/quote]
0 votes
by (162k points)
We'd like to help, but I'm not really sure how. Make a sensible suggestion of what we could do to the logging API (with a bit of detail) and we'll look at implementing it, possibly in 1.1.1.

One possibility that comes to mind is allowing the user to replace the Logger object (the class-wide one) with an instance-specific one. This could be done by calling the Logger instance classname+uniqueId. You then need the ability to configure different destinations for different loggers - currently Appenders apply for all Loggers. This ability is a feature of log4j and something we were planning on adding anyway.

Let us know what you think.

Here's the rest of the problem. The different objects that I mentioned are in fact created through HTTP requests to a servlet. The servlet then makes an FTPS request. When I service an HTTP request, I need to return to the client the debug (log trace) for the FTPS session.
0 votes
by (600 points)
I already have the ability to configure different destinations for each instance, so I think this would probably work. I'm a bit hazy on why you mean by calling "Logger instance classname+uniqueid". Do you have a simple example?

Would 1.1.1 be available sometime by the mid to end of June?

Thanks,
Steve

[quote="support2"]We'd like to help, but I'm not really sure how. Make a sensible suggestion of what we could do to the logging API (with a bit of detail) and we'll look at implementing it, possibly in 1.1.1.

One possibility that comes to mind is allowing the user to replace the Logger object (the class-wide one) with an instance-specific one. This could be done by calling the Logger instance classname+uniqueId. You then need the ability to configure different destinations for different loggers - currently Appenders apply for all Loggers. This ability is a feature of log4j and something we were planning on adding anyway.

Let us know what you think.

[quote="reichesf"]Here's the rest of the problem. The different objects that I mentioned are in fact created through HTTP requests to a servlet. The servlet then makes an FTPS request. When I service an HTTP request, I need to return to the client the debug (log trace) for the FTPS session.
[/quote][/quote]
0 votes
by (162k points)
You'll need a API call on FTPClient/SSLFTPClient (and all classes that log)called, say,

public void setLogger(Logger log)

and we'll need to make the log variable in each class non-static.

You would construct the log object yourself and make it unique by appending your unique session id to the classname:

Logger mylog = Logger.getLogger("com.enterprisedt.net.ftp.ssl.SSLFTPClient_sessionid);

setLogger() would replace the current class logger with your own. Easy enough to do (but you'd need to do it for all classes that log - 3 or 4 of them). I don't think it will be possible at the moment to do this for the ssl logging - hopefully this will be sufficient for you.

Now, you need to be able to configure the Logger so that for a given FileAppender, log output only goes to the Logger you specify.

This will require another call:

Logger.addAppender(Logger log, Appender newAppender);

So now your log instance sends its output to only the Appender.

A clearLogger() would also be required to remove Loggers when no longer required, otherwise they will build up (in your case anyway).

I need to talk this one over - it has a yucky feel to it - so I'll have to get back to you. There may be a better approach I haven't thought of, and implications I haven't considered.

However I imagine it won't take long to get implemented once we make a decision, and we can make sure it is ready by mid June.

I already have the ability to configure different destinations for each instance, so I think this would probably work. I'm a bit hazy on why you mean by calling "Logger instance classname+uniqueid". Do you have a simple example?

Would 1.1.1 be available sometime by the mid to end of June?
0 votes
by (600 points)
Sounds like a very reasonable approach to start with. I believe that would work just fine.

With the current logging, it appears that you need to to call the "shutdown()" method to get the log to flush to disk properly. Would there also need to be something in this (a flush()) that would cause the log data to flush to disk?

Thanks for the very quick responses, and if you get the chance, let me know what happens. For now, I'll work with the current "Logger".

Steve


[quote="support2"]You'll need a API call on FTPClient/SSLFTPClient (and all classes that log)called, say,

public void setLogger(Logger log)

and we'll need to make the log variable in each class non-static.

You would construct the log object yourself and make it unique by appending your unique session id to the classname:

Logger mylog = Logger.getLogger("com.enterprisedt.net.ftp.ssl.SSLFTPClient_sessionid);

setLogger() would replace the current class logger with your own. Easy enough to do (but you'd need to do it for all classes that log - 3 or 4 of them). I don't think it will be possible at the moment to do this for the ssl logging - hopefully this will be sufficient for you.

Now, you need to be able to configure the Logger so that for a given FileAppender, log output only goes to the Logger you specify.

This will require another call:

Logger.addAppender(Logger log, Appender newAppender);

So now your log instance sends its output to only the Appender.

A clearLogger() would also be required to remove Loggers when no longer required, otherwise they will build up (in your case anyway).

I need to talk this one over - it has a yucky feel to it - so I'll have to get back to you. There may be a better approach I haven't thought of, and implications I haven't considered.

However I imagine it won't take long to get implemented once we make a decision, and we can make sure it is ready by mid June.

[quote="reichesf"]I already have the ability to configure different destinations for each instance, so I think this would probably work. I'm a bit hazy on why you mean by calling "Logger instance classname+uniqueid". Do you have a simple example?

Would 1.1.1 be available sometime by the mid to end of June?
[/quote][/quote]
0 votes
by (162k points)
Discussions indicate lack of enthusiasm for the above solution. The suggestion is to ask you what you require.

Do you just require a log of FTP messages and responses to pass back to the client? This is the major part of logging output.

If so, the suggestion is to define a listener interface:


public interface FTPMessageListener {

public void logCommand(String cmd);
public void logReply(String reply);
}

and FTPClient.setMessageListener(FTPMessageListener listener);

So you can implement the interface (e.g. with a buffer to collect all the messages) and set it for each FTPClient instance.

Will this do what you require?


Sounds like a very reasonable approach to start with. I believe that would work just fine.
0 votes
by (600 points)
Yes, this is really what I was looking for. I can trap for appropriate exceptions as I call the client methods and log those on my own. In addition, we'd still have the global log4j style log.

Sounds like the best overall solution.

Thanks for your patience in addressing this. If you get a chance, let me know the status of this.

Steve

[quote="support2"]Discussions indicate lack of enthusiasm for the above solution. The suggestion is to ask you what you require.

Do you just require a log of FTP messages and responses to pass back to the client? This is the major part of logging output.

If so, the suggestion is to define a listener interface:


public interface FTPMessageListener {

public void logCommand(String cmd);
public void logReply(String reply);
}

and FTPClient.setMessageListener(FTPMessageListener listener);

So you can implement the interface (e.g. with a buffer to collect all the messages) and set it for each FTPClient instance.

Will this do what you require?


[quote="reichesf"]Sounds like a very reasonable approach to start with. I believe that would work just fine.[/quote][/quote]
0 votes
by (162k points)
Excellent! This will be very straightforward to implement, and we'll add it to 1.1.1. We expect 1.1.1 to be available around about the end of May. If you send an email to support-at-enterprisedtcom-dot-com we'll send 1.1.1 to you when it is released. Otherwise we can send it to the contact email listed in your co's order.

Yes, this is really what I was looking for. I can trap for appropriate exceptions as I call the client methods and log those on my own. In addition, we'd still have the global log4j style log.

Sounds like the best overall solution.

Thanks for your patience in addressing this. If you get a chance, let me know the status of this.

Steve
0 votes
by (600 points)
Thanks again. I will send the email to support. I have one question though: Do I need to reference a customer # or something? If so, I'll track that down. All I received was a copy of the email that included the archive.

Steve


[quote="support2"]Excellent! This will be very straightforward to implement, and we'll add it to 1.1.1. We expect 1.1.1 to be available around about the end of May. If you send an email to support-at-enterprisedtcom-dot-com we'll send 1.1.1 to you when it is released. Otherwise we can send it to the contact email listed in your co's order.

[quote="reichesf"]Yes, this is really what I was looking for. I can trap for appropriate exceptions as I call the client methods and log those on my own. In addition, we'd still have the global log4j style log.

Sounds like the best overall solution.

Thanks for your patience in addressing this. If you get a chance, let me know the status of this.

Steve
[/quote][/quote]

Categories

...