- SSH or telnet to the machine and use the commandLine LogViewer or the API
- zip up the log repository (logs directory, usually <profileHome>/logs/<serverName>, and send it to the machine where you want to do the analysis
- Use the Admin Console LogViewer
- Use the API to access remote content.
The first 3 are pretty self-explanatory (if not, let me know), so we're going to focus on on #4. HPEL employs JMX to communicate to remote machines. If you've used a JMX before, please don't quit yet. We have layered around it with some helper classes which makes it almost painless (OK, yes you need the thinClient jar, and if there is security in the cell or server ... you do need to deal with that in your env vars et al ... but bear with us here). What you'll notice is that accessing logs from a remote server is the same as accessing logs from a local server. In our example here, we're only going for information from the current serverInstance, but you could get data from any or all server instances with one query. In that you are sending data potentially through many hops, you will want to use some of the filtering we'll see soon on this blog. The hops come in when you connect your machine to the DMgr which connects through a NodeAgent to a server .. your data has to go from the server to the nodeAgent, to the DMgr, and back to you. That's a fair amount of serialize/deSerialize and transport. Thus, while you can bring back as much data as you'd like, doing some smart filtering is a good idea.
So we have annotated a sample that gets all Info, Warning, and Severe messages from a remote server. It does use a helper class which protects you from doing any JMX yourself, and that helper (and more) were referenced in the last blog entry (and if you can somehow find my file uploads, it is there too). So let's look at our sample code first.
public class RemoteReaderSample {
public static void main(String[] args) {
// Create simple reader object with the WebSphere topology and network topology info
if (args.length < 6) {
1 System.out.println("Usage is: java RemoteReaderSample <cellName> <nodeName> <serverName> <hostName> <hostPort> <connectionType> [<serverContext>]");
System.out.println(" ie: java RemoteReaderSample mycell mynode server1 localhost 8880 soap mycell/mynode/myserver");
System.exit(-1) ;
}
2 String serverContext = (args.length > 6) ? args[6] : null ;
System.out.println("Using: Cell: "+args[0]+" node: "+args[1]+" server: "+args[2]+" host: "+args[3]+
" port: "+args[4]+" connType: "+args[5]+" serverContext: "+serverContext) ;
RemoteReaderHelper simpleRemoteReader = null ;
try {
3 simpleRemoteReader = new RemoteReaderHelper(args[0], args[1], args[2],
args[3], args[4], args[5], serverContext) ;
} catch (Exception e) {
System.out.println("Exception in constructing RemoteReaderHelper: "+e);
e.printStackTrace() ;
System.exit(0) ;
}
// Use remote reader and get list of all Warning and Errors from the current server instance of
// the remote server. Can go across server instances, and numerous filtering options are available.
// For remote API, it is important to filter in this call where possible to reduce the # of rows from
// the remote log that come back.
ServerInstanceLogRecordList silrl = null ;
try {
4 silrl = simpleRemoteReader.getLogListForServerInstance((Date)null, Level.INFO,
Level.SEVERE);
} catch (LogRepositoryException e) {
System.out.println("Data retrieval resulted in an exception: "+e);
e.printStackTrace();
System.exit(-99) ;
}
try {
5 for (RepositoryLogRecord logRec : silrl) {
System.out.println(logRec.getFormattedMessage());
}
} catch (LogRepositoryRuntimeException lrre) {
6 System.out.println("Runtime Exception caught retrieving log repository data: "+lrre);
}
}
}
So to discuss these points by the numbers:
- You need to pass in all the parms needed to contact a JMX server and give it addressability to the server you're interested in. So the cell, node, and server tell us what server you want to talk to, and the host, port, and connection type connect you to a JMX server in the cell.
- So what's with that serverContext? Well, what if the server whose logs you want to view is down? You cannot get to an MBean if the server is down. This allows you to hook in to the nodeAgent instead of the server, but tell the MBean in the NodeAgent not to get his logs, but instead to get the logs from the server you specify in the server context.
- You pass all the startup parms to the RemoteReaderHelper so that he can do all the JMX plumbing we all hate to do
- This single line does all the real HPEL work for you, so let's look at it.
- Note that the helper class takes the same APIs as the local sample since it is a subClass of the API itself, so what works with the local API works with the remote
- The first parameter here needs to be a Date that will identify which serverInstance you are interested in. By leaving the Date null, the assumption is that you want the latest serverInstance
- The next parms are one signature for this method that allows you to specify message severity. We'll later look at using a LogQueryBean which enables serious filtering
- That query (since it was only one serverInstance) allows you to iterate through the log records that met your criteria with this simple for statement
- Note that we kept it brief by just doing getFormattedMessage(). Every piece of information from the logRecord is retrievable as we'll see later.
Note: If you look at public files from me, you will find the library of samples which includes the helper classes.