+1 vote
1.8k views
in Javascript API by (30.6k points)

1 Answer

0 votes
by (30.6k points)

Server-side scripts have only log.info() (goes to SystemOut.log). For your own log file per process app or per instance, use a small Java integration with Log4j (or java.util.logging) in a managed jar and keep the logger name / file per app:

// Java (log4j 2): one logger per process app, file per app; called from a Java Integration "Log"
public class AppLogger {
  private static final java.util.concurrent.ConcurrentHashMap<String, Logger> LOGGERS = new java.util.concurrent.ConcurrentHashMap<>();
  public static void log(String app, String level, String piid, String message) {
    Logger l = LOGGERS.computeIfAbsent(app, AppLogger::create);
    String line = "[" + piid + "] " + message;
    switch (level) { case "ERROR": l.error(line); break; case "WARN": l.warn(line); break; case "DEBUG": l.debug(line); break; default: l.info(line); }
  }
  private static Logger create(String app) {
    LoggerContext ctx = (LoggerContext) LogManager.getContext(false); Configuration cfg = ctx.getConfiguration();
    String dir = System.getProperty("bpm.app.log.dir", "/var/log/bpm");
    Appender ap = RollingFileAppender.newBuilder().setName("app-" + app).withFileName(dir + "/" + app + ".log")
        .withFilePattern(dir + "/" + app + "-%d{yyyy-MM-dd}.log.gz").withPolicy(TimeBasedTriggeringPolicy.newBuilder().build())
        .setLayout(PatternLayout.newBuilder().withPattern("%d %-5p %m%n").build()).setConfiguration(cfg).build();
    ap.start(); cfg.addAppender(ap);
    LoggerConfig lc = new LoggerConfig("bpm.app." + app, Level.DEBUG, false); lc.addAppender(ap, null, null);
    cfg.addLogger("bpm.app." + app, lc); ctx.updateLoggers(); return ctx.getLogger("bpm.app." + app);
  }
}
// toolkit service flow "Log" (inputs level, message) - script before the Java step
tw.local.app  = tw.system.model.processApp.acronym;
tw.local.piid = tw.system.currentProcessInstanceID != null ? tw.system.currentProcessInstanceID : "-";
// Java Integration: AppLogger.log(app, level, piid, message)

Notes: the log directory must exist on every cluster member (or use a shared NFS path); rotate with the time-based policy; put the toolkit service in every app so that the call is one step (Log with level + message); never log full business objects with personal data; on CP4BA write to stdout instead (the platform collects it) - log.info("[" + app + "][" + piid + "] " + message) with a structured prefix is enough for the log stack to filter per app. Also see question 107 for the other logging options.

References

Related questions

0 votes
1 answer 2.5k views
0 votes
3 answers 1.7k views
0 votes
1 answer 762 views
0 votes
1 answer 3.1k views
0 votes
1 answer 2.6k views
0 votes
1 answer 1.4k views
0 votes
1 answer 1.9k views
0 votes
1 answer 1.0k views
0 votes
1 answer 2.0k views

723 questions

807 answers

98 comments

4.9k users

Join BPM Community Discord Channel

Welcome to BPM Tips Q&A, Community wiki/forum where you can ask questions and receive answers from other IBM BPM experts and members of the community. Users with 2000 points will automatically be promoted to expert level.
Created by Dosvak LLC
Our Youtube Channel
...