Skip to content

Commit

Permalink
[ADD] Log targets. #2168
Browse files Browse the repository at this point in the history
  • Loading branch information
ChristianGruen committed Sep 17, 2024
1 parent f48a371 commit e3c65e2
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 24 deletions.
2 changes: 1 addition & 1 deletion basex-api/src/main/java/org/basex/BaseXHTTP.java
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ protected void parseArgs() throws IOException {
Prop.put(StaticOptions.USER, arg.string());
break;
case 'z': // suppress logging
Prop.put(StaticOptions.LOG, Boolean.FALSE.toString());
Prop.put(StaticOptions.LOG, "");
break;
default:
throw arg.usage();
Expand Down
2 changes: 1 addition & 1 deletion basex-core/src/main/java/org/basex/BaseXServer.java
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ protected void parseArgs() throws IOException {
service = !daemon;
break;
case 'z': // suppress logging
context.soptions.set(StaticOptions.LOG, Boolean.FALSE.toString());
context.soptions.set(StaticOptions.LOG, "");
break;
default:
throw arg.usage();
Expand Down
2 changes: 1 addition & 1 deletion basex-core/src/main/java/org/basex/core/StaticOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ public final class StaticOptions extends Options {
/** Defines the number of parallel readers. */
public static final NumberOption PARALLEL = new NumberOption("PARALLEL", 8);
/** Logging flag. */
public static final StringOption LOG = new StringOption("LOG", "true");
public static final StringOption LOG = new StringOption("LOG", "data");
/** Log message cut-off. */
public static final NumberOption LOGMSGMAXLEN = new NumberOption("LOGMSGMAXLEN", 1000);
/** Write trace output to the logs. */
Expand Down
83 changes: 62 additions & 21 deletions basex-core/src/main/java/org/basex/server/Log.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,20 @@ public enum LogType {
/** Error. */ ERROR,
/** OK. */ OK
}
/** Log targets. */
private enum LogTarget {
/** Standard out. */ STDOUT,
/** Standard error. */ STDERR,
/** Database directory. */ DATA
}

/** Static options. */
private final StaticOptions sopts;
/** Maximum length of log messages. */
private final int maxLen;

/** Log targets. */
private Set<LogTarget> targets;
/** Current log file. */
private LogFile file;

Expand All @@ -50,6 +60,7 @@ public enum LogType {
*/
public Log(final StaticOptions sopts) {
this.sopts = sopts;
maxLen = sopts.get(StaticOptions.LOGMSGMAXLEN);
}

/**
Expand Down Expand Up @@ -117,51 +128,81 @@ public void write(final Object type, final String info, final Performance perf,
* @param address address string ({@code SERVER} is written if value is {@code null})
* @param user user ({@code admin} is written if value is {@code null})
*/
private void write(final String type, final String info, final Performance perf,
private synchronized void write(final String type, final String info, final Performance perf,
final String address, final String user) {

// check if logging is disabled
final String log = sopts.get(StaticOptions.LOG);
if(Strings.no(log)) return;
if(skip()) return;

// construct log text
final Date date = new Date();
final int ml = sopts.get(StaticOptions.LOGMSGMAXLEN);
final TokenBuilder tb = new TokenBuilder();
tb.add(DateTime.format(date, DateTime.TIME));
tb.add('\t').add(address != null ? address.replaceFirst("^/", "") : SERVER);
tb.add('\t').add(user != null ? user : UserText.ADMIN);
tb.add('\t').add(type);
tb.add('\t').add(info != null ? chop(normalize(token(info)), ml) : EMPTY);
tb.add('\t').add(info != null ? chop(normalize(token(info)), maxLen) : EMPTY);
if(perf != null) tb.add('\t').add(perf);
tb.add(Prop.NL);
final byte[] token = tb.finish();

try {
synchronized(sopts) {
// create new log file and write log entry
final String name = DateTime.format(date, DateTime.DATE);
if(file != null && !file.valid(name)) close();
if(file == null) file = LogFile.create(name, dir());
// write log entry
final byte[] token = tb.toArray();
file.write(token);
if(log.equals("stdout")) Util.print(string(token));
// use existing or create new log file
final String name = DateTime.format(date, DateTime.DATE);
if(file != null && !file.valid(name)) close();
if(file == null) file = LogFile.create(name, dir());

// write log entry to requested targets
for(final LogTarget target : targets) {
switch(target) {
case STDOUT:
Util.print(string(token));
break;
case STDERR:
Util.err(string(token));
break;
default:
file.write(token);
}
}
} catch(final IOException ex) {
Util.stack(ex);
}
}

/**
* Checks if logging is requested. Initializes the log targets if not done yet
* (not part of the constructor to consider command-line arguments).
* @return result of check
*/
private boolean skip() {
if(targets == null) {
final String log = sopts.get(StaticOptions.LOG);
final Set<LogTarget> set = EnumSet.noneOf(LogTarget.class);
for(final String target : log.trim().toUpperCase().split("\\s*,\\s*")) {
if(Strings.no(target)) {
set.clear();
break;
} else if(Strings.toBoolean(target)) {
set.add(LogTarget.DATA);
} else {
for(final LogTarget lt : LogTarget.values()) {
if(target.equals(lt.name())) set.add(lt);
}
}
}
targets = set;
}
return targets.isEmpty();
}

/**
* Closes the log file.
*/
public void close() {
public synchronized void close() {
try {
synchronized(sopts) {
if(file != null) {
file.close();
file = null;
}
if(file != null) {
file.close();
file = null;
}
} catch(final IOException ex) {
Util.stack(ex);
Expand Down

0 comments on commit e3c65e2

Please sign in to comment.