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.