3 Replies Latest reply on Oct 27, 2014 10:05 AM by Derek F

    How to log output to a file

    Derek F Newbie



      I have attempted to use byteman to log out information to assist in troubleshooting an issue.


      My concern is that I am not able to get this to log to a file - and all the output to the console will be very difficult to manage.  I would just like to record my specific debugging to a file for parsing.


      I tried this:


      RULE JMS Message Rule

      CLASS com.myco.MyClass

      METHOD void processEvent(com.myco.Event)

      IF true

      DO traceOpen("x", "c:\TEMP\text.txt");

      traceln("x","entering processEvent " + $1.getEventType());

      traceln("x","dispatched by: " + $1.getLoginName());



      This doesn't output anything.  If I just do  traceln("entering processEvent " + $1.getEventType()) I will see the output on the console.


      I have also just tried without qualifying the file name, and that doesn't work.


      Any help would be greatly appreciated.

        • 1. Re: How to log output to a file
          Andrew Dinn Master

          Hi Derek,


          As you can probably guess from my working at Red Hat I don't normally use Byteman on Windows -- I normally need to borrow someone's Windows box to do so. On occasions I have done so and tested Byteman and I feel fairly sure I have managed to use traceOpen and trace before. Many Byteman users do run it on Windows so maybe someone else can help here.


          Anyway, if there is a problem then it may be to do with


          1. the syntax you are using for the file name
          2. the file access permissions of the Java process running your program
          3. a bug in the traceOpen code


          The traceOpen call is implemented by method Helper.traceOpen() -- any standard builtin method like traceOpen belongs to class Helper in package org.jboss.byteman.rule.helper. Here is the code:


              public  boolean traceOpen(Object identifier, String fileName)
                  if (identifier == null) {
                      return false;
                  synchronized(traceMap) {
                      PrintStream stream = traceMap.get(identifier);
                      String name = fileName;
                      if (stream != null) {
                          return false;
                      if (fileName == null) {
                          name = nextFileName();
                      File file = new File(name);
                      if (file.exists() && !file.canWrite()) {
                          if (fileName == null) {
                              // keep trying new names until we hit an unused one
                              do {
                                  name = nextFileName();
                                  file = new File(name);
                              } while (file.exists() && !file.canWrite());
                          } else {
                              // can't open file as requested
                              return false;
                      FileOutputStream fos;
                      try {
                          if (file.exists()) {
                              fos = new FileOutputStream(file, true);
                          } else {
                              fos = new FileOutputStream(file, true);
                      } catch (FileNotFoundException e) {
                          // oops, just return false
                          return false;
                      PrintStream ps = new PrintStream(fos, true);
                      traceMap.put(identifier, ps);
                      return true;


          Hmm, I can already see a few things that are not quite right but I don't think they necessarily account for your problem.


          First off let's note that the name you provide is passed to new File() at line 15. So, if there is a problem with the file name syntax then you could test that by writing a small Java program which tries to open a file using name "c:\TEMP\text.txt". If it fails to open with an exception print the exception to see what is wrong. That might indicate an error in the syntax or a permissions error caused by the way the file system is set up or the way your process is being run.


          I don't see anything in the code whcih might account for te behaviour you are seeing. The errors I can see in the implementation are as follows:


          At line 15 if a read only file with the supplied name is found then nextFileName() is called to magic up a new file name of the form temp001.txt, temp002.txt etc. That's ok if you didn't provide a name in the first place but is no good if you gave a specific name. However, that doesn't account for your error where the text goes to System.out


          At lines 31 and 33 the file is opened with the 2nd argument (append mode flag) true. This is fine as far as correctness is concernwd as appending to a non-existent file is the same as writing to the start of the file and appending to an existing file is the documented behaviour for that case The error here is that the if/else branching is redundant.


          If you can run a simple file open test and tell me what happens I might be able to help you further.





          Andrew Dinn

          • 2. Re: How to log output to a file
            Andrew Dinn Master

            Oops. I wrote better code than I realised!


            Of course at line 15 name is only updated if filename == null i.e if no name was supplied in the original call.


            So, the only error I can see is the redundant if/else clause at lines 31/33.

            • 3. Re: How to log output to a file
              Derek F Newbie

              Thanks - I didn't see that I needed to add the helper class to perform this function.


              Works like a charm now.