12
$\begingroup$

Someone has a code example of how log4j can be used to create logs in Mathematica?

RLink uses it, as can be checked in initLogger[] function, in this file:

SystemOpen@FileNameJoin@{DirectoryName@DirectoryName@FindFile["RLink`"], "RLink.m"}

But it's not a stand alone code. If someone has a simpler one, I would appreciate.

$\endgroup$
5
  • 1
    $\begingroup$ One username comes to my mind :) $\endgroup$ Commented Oct 4, 2015 at 0:17
  • $\begingroup$ @belisarius yes... some friend, that as you, has more than 70k points. $\endgroup$ Commented Oct 4, 2015 at 0:22
  • $\begingroup$ Well, the code in RLink pretty much shows how this can be used. The only missing piece is the logger instance, which is referred there as RLinkInit`rlogger, and for which instead you can use Logger`getLogger["YourApp"]. And you will have to first LoadJavaClass["org.apache.log4j.Logger"], and add the log4j.jar to the classpath. $\endgroup$ Commented Oct 4, 2015 at 0:24
  • $\begingroup$ @LeonidShifrin, interesting. Now I'm a little more comfortable with Java and Mathematica. I'll make some tests. tks $\endgroup$ Commented Oct 4, 2015 at 0:30
  • $\begingroup$ I will post a minimal code, in a moment. $\endgroup$ Commented Oct 4, 2015 at 0:39

1 Answer 1

8
$\begingroup$

Minimal code

Here is a minimal code (partly adopted from RLink), to get you started. First, load JLink:

Needs["JLink`"]
InstallJava[]

Here is the code:

ClearAll[logIt];
logIt[logger_,msg_String,mode_String]:=
  Block[{trace, debug, info, warn, error, fatal},
    With[{
      method = mode /. {
        "TRACE" -> trace, 
        "DEBUG" -> debug, 
        "INFO" -> info, 
        "WARN" -> warn, 
        "FATAL" -> fatal,
        _ :> Return[$Failed, Block]
      }},
      JavaBlock@logger@method[JavaNew["java.lang.String", msg]]
    ]
  ];

logIt[logger_,msg_String]:=logIt[logger, msg, "INFO"];

And the initLogger function:

ClearAll[initLogger];
initLogger[logger_, logFile_]:=
  Module[{},        
    logger@removeAllAppenders[];
    logger@addAppender[
      JavaNew["org.apache.log4j.ConsoleAppender"]
    ];
    logger@addAppender[
      JavaNew[
        "org.apache.log4j.FileAppender", 
        JavaNew["org.apache.log4j.SimpleLayout"],           
        logFile
      ]
    ];
    logIt[logger, "Logger initialized"];
  ];    

Example of use

Here is an example (I assume that log4j is already on the classpath, which is usually so, because it is used also internally in Mathematica):

LoadJavaClass["org.apache.log4j.Logger"]

Now create a logger instance:

logger = Logger`getLogger["MyApp"]

(* « JavaObject[org.apache.log4j.Logger]» *)

and the log file:

$logFile = FileNameJoin[{$TemporaryDirectory, "mylog.txt"}];

Now, initialize the logger:

initLogger[logger, $logFile]

You can test:

Import[$logFile, "String"]

(* "INFO - Logger initialized" *)

Now log something:

Do[
  If[i < 5, 
    logIt[logger, "i = " <> ToString [i]], 
    logIt[logger, "fatal error", "FATAL"]; Break[]
  ], 
  {i, 1, 10}
]

check:

Import[$logFile, "String"]

"INFO - Logger initialized
 INFO - i = 1
 INFO - i = 2
 INFO - i = 3
 INFO - i = 4
 FATAL - fatal error"

You can do more interesting things with loggers with log4j, but this example should get you started.

$\endgroup$
3
  • $\begingroup$ Tks a lot! Works like a charm! +1 $\endgroup$ Commented Oct 4, 2015 at 1:07
  • $\begingroup$ @Murta Glad to help, as usual. Thanks for the accept! $\endgroup$ Commented Oct 4, 2015 at 13:11
  • 1
    $\begingroup$ @Murta Of course, the real reason why I used log4j in RLink is that I could append to the logger on both Mathematica and Java sides of RLink. If you only need Mathematica - side, you can simply use appending to a file. But for the hybrid Java / Mathematica apps, being able to use one and the same logger for both sides is important. The way you do this is to have a logger be a field of some Java class on the Java side, and then pass that instance to Mathematica. For RLink, the logger is a (static) field of RLinkInit class , accessed via RLinkInit`rlogger in Mathematica. $\endgroup$ Commented Oct 4, 2015 at 15:07

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.