Skip to content

Commit

Permalink
add logging level
Browse files Browse the repository at this point in the history
  • Loading branch information
avarsava committed Jun 26, 2024
1 parent 0d50ff4 commit 4e2e86c
Show file tree
Hide file tree
Showing 14 changed files with 73 additions and 36 deletions.
12 changes: 11 additions & 1 deletion docs/plugin-loki.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,23 @@ ending `.loki` with the following:
"url": "http://your.loki.server/loki/api/v1/push",
"labels": {
"environment": "foo"
}
},
"level": INFO
}

The `"url"` property is the URL of the Loki server to push logs into. The
optional `"labels"` object will apply static labels to all values logged from
this instance.

The `"level"` property is one of:
1. FATAL
2. ERROR
3. WARN
4. INFO
5. DEBUG

All messages at or above the setting in severity will be logged to Loki.

## For Plugin Developers
The PluginManager passes each `PluginFileType` an implementation of `Definer` which has
a method `log(String, Map<String,String>)`. If the Loki plugin is installed, then the PluginManager will route log
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,7 @@

import ca.on.oicr.gsi.prometheus.LatencyHistogram;
import ca.on.oicr.gsi.shesmu.cromwell.WorkflowIdAndStatus;
import ca.on.oicr.gsi.shesmu.plugin.Definer;
import ca.on.oicr.gsi.shesmu.plugin.FrontEndIcon;
import ca.on.oicr.gsi.shesmu.plugin.MultiPartBodyPublisher;
import ca.on.oicr.gsi.shesmu.plugin.Utils;
import ca.on.oicr.gsi.shesmu.plugin.*;
import ca.on.oicr.gsi.shesmu.plugin.action.ActionCommand;
import ca.on.oicr.gsi.shesmu.plugin.action.ActionCommand.Preference;
import ca.on.oicr.gsi.shesmu.plugin.action.ActionServices;
Expand Down Expand Up @@ -373,7 +370,7 @@ private void showError(HttpResponse<?> response, URI url)
final List<String> errors = new ArrayList<>();
final Map<String, String> labels = new TreeMap<>();
labels.put("url", url.getHost());
owner.log("HTTP error: " + response.statusCode(), labels);
owner.log("HTTP error: " + response.statusCode(), LogLevel.ERROR, labels);
errors.add("HTTP error: " + response.statusCode());
this.errors = errors;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package ca.on.oicr.gsi.shesmu.jira;

import ca.on.oicr.gsi.shesmu.plugin.Definer;
import ca.on.oicr.gsi.shesmu.plugin.LogLevel;
import ca.on.oicr.gsi.shesmu.plugin.action.ActionState;
import java.io.IOException;
import java.net.URISyntaxException;
Expand Down Expand Up @@ -61,7 +62,8 @@ public ActionState perform(
Map<String, String> lokiLabels = new HashMap<>();
lokiLabels.put("issue", issue.getKey());
lokiLabels.put("verb", "close");
((Definer<JiraConnection>) definer).log(errorBuilder.toString(), lokiLabels);
((Definer<JiraConnection>) definer)
.log(errorBuilder.toString(), LogLevel.ERROR, lokiLabels);
return ActionState.FAILED;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import ca.on.oicr.gsi.shesmu.jira.Issue.Field;
import ca.on.oicr.gsi.shesmu.plugin.Definer;
import ca.on.oicr.gsi.shesmu.plugin.FrontEndIcon;
import ca.on.oicr.gsi.shesmu.plugin.LogLevel;
import ca.on.oicr.gsi.shesmu.plugin.Tuple;
import ca.on.oicr.gsi.shesmu.plugin.action.ActionState;
import ca.on.oicr.gsi.shesmu.plugin.action.ShesmuAction;
Expand Down Expand Up @@ -456,7 +457,8 @@ boolean transition(
.append(transitionResult.body());
Map<String, String> lokiLabels = new HashMap<>();
lokiLabels.put("issue", issue.getKey());
((Definer<JiraConnection>) definer).log(errorBuilder.toString(), lokiLabels);
((Definer<JiraConnection>) definer)
.log(errorBuilder.toString(), LogLevel.ERROR, lokiLabels);
return false;
} else {
return true;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package ca.on.oicr.gsi.shesmu.loki;

import ca.on.oicr.gsi.shesmu.plugin.LogLevel;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import java.util.Map;

Expand All @@ -8,6 +9,7 @@
public class Configuration {
private Map<String, String> labels = Map.of();
private String url;
private LogLevel level;

public Map<String, String> getLabels() {
return labels;
Expand All @@ -24,4 +26,12 @@ public void setLabels(Map<String, String> labels) {
public void setUrl(String url) {
this.url = url;
}

public LogLevel getLevel() {
return level;
}

public void setLevel(LogLevel level) {
this.level = level;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import ca.on.oicr.gsi.Pair;
import ca.on.oicr.gsi.prometheus.LatencyHistogram;
import ca.on.oicr.gsi.shesmu.plugin.Definer;
import ca.on.oicr.gsi.shesmu.plugin.LogLevel;
import ca.on.oicr.gsi.shesmu.plugin.json.JsonPluginFile;
import ca.on.oicr.gsi.status.SectionRenderer;
import com.fasterxml.jackson.databind.ObjectMapper;
Expand Down Expand Up @@ -58,6 +59,7 @@ public void configuration(SectionRenderer renderer) {
configuration.ifPresent(
configuration -> {
renderer.link("Instance", configuration.getUrl(), configuration.getUrl());
renderer.line("Level", configuration.getLevel().toString());
for (final var entry : configuration.getLabels().entrySet()) {
renderer.line("Label: " + entry.getKey(), entry.getValue());
}
Expand Down Expand Up @@ -160,9 +162,10 @@ protected synchronized Optional<Integer> update(Configuration configuration) {
}

@Override
public synchronized void writeLog(String message, Map<String, String> attributes) {
public synchronized void writeLog(
String message, LogLevel level, Map<String, String> attributes) {
final var now = Instant.now();
buffer.computeIfAbsent(attributes, k -> new ArrayList<>()).add(new Pair<>(now, message));
flush(now);
if (level.compareTo(this.configuration.get().getLevel()) >= 0) flush(now);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import ca.on.oicr.gsi.prometheus.LatencyHistogram;
import ca.on.oicr.gsi.shesmu.plugin.AlgebraicValue;
import ca.on.oicr.gsi.shesmu.plugin.Definer;
import ca.on.oicr.gsi.shesmu.plugin.LogLevel;
import ca.on.oicr.gsi.shesmu.plugin.Tuple;
import ca.on.oicr.gsi.shesmu.plugin.action.ActionState;
import ca.on.oicr.gsi.shesmu.plugin.action.ShesmuAction;
Expand Down Expand Up @@ -176,7 +177,7 @@ public Thread drainOutput(
labels.put("type", "refiller");
labels.put("stream", stream);
final var errorDrainThread =
new Thread(() -> errorReader.lines().forEach(l -> definer.log(l, labels)));
new Thread(() -> errorReader.lines().forEach(l -> definer.log(l, LogLevel.ERROR, labels)));
errorDrainThread.start();
return errorDrainThread;
}
Expand Down Expand Up @@ -314,7 +315,7 @@ public boolean refill(String name, String command, ArrayNode data) {
labels.put("command", command);
labels.put("name", name);
labels.put("type", "refiller");
definer.log("Expected OK or UPDATE, but got no output", labels);
definer.log("Expected OK or UPDATE, but got no output", LogLevel.ERROR, labels);
} else {
switch (response) {
case "UPDATE":
Expand Down Expand Up @@ -355,7 +356,10 @@ public boolean refill(String name, String command, ArrayNode data) {
labels.put("command", command);
labels.put("name", name);
labels.put("type", "refiller");
definer.log("Expected OK or UPDATE, but got invalid response: " + response, labels);
definer.log(
"Expected OK or UPDATE, but got invalid response: " + response,
LogLevel.ERROR,
labels);
break;
}
}
Expand Down Expand Up @@ -509,7 +513,7 @@ protected Optional<Object> fetch(Tuple key, Instant lastUpdated) throws Exceptio
labels.put("command", command);
labels.put("name", name);
labels.put("type", "function");
errorReader.lines().forEach(l -> definer.log(l, labels));
errorReader.lines().forEach(l -> definer.log(l, LogLevel.ERROR, labels));
process.join();
if (process.getExitStatus() == null || process.getExitStatus() != 0) {
return Optional.empty();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -296,5 +296,5 @@ <R> String defineStaticSigner(
* @param message the log message to write
* @param labels the labels associated with this message
*/
void log(String message, Map<String, String> labels);
void log(String message, LogLevel level, Map<String, String> labels);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package ca.on.oicr.gsi.shesmu.plugin;

public enum LogLevel {
DEBUG,
INFO,
WARN,
ERROR,
FATAL
}
Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,10 @@ public void stop() {}
* service. To write logs, use {@link Definer#log(String, Map)}
*
* @param message the log message to write
* @param level the logging level of this message
* @param attributes the labels associated with this message
*/
public void writeLog(String message, Map<String, String> attributes) {
public void writeLog(String message, LogLevel level, Map<String, String> attributes) {
// Do nothing
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -170,9 +170,10 @@ public void writeJavaScriptRenderer(PrintStream writer) {}
* service. To write logs, use {@link Definer#log(String, Map)}
*
* @param message the log message to write
* @param level the logging level of this message
* @param attributes the labels associated with this message
*/
public void writeLog(String message, Map<String, String> attributes) {
public void writeLog(String message, LogLevel level, Map<String, String> attributes) {
// Do nothing
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import ca.on.oicr.gsi.shesmu.core.StandardDefinitions;
import ca.on.oicr.gsi.shesmu.plugin.ErrorableStream;
import ca.on.oicr.gsi.shesmu.plugin.FrontEndIcon;
import ca.on.oicr.gsi.shesmu.plugin.LogLevel;
import ca.on.oicr.gsi.shesmu.plugin.SourceLocation;
import ca.on.oicr.gsi.shesmu.plugin.action.Action;
import ca.on.oicr.gsi.shesmu.plugin.action.ActionCommand.Preference;
Expand Down Expand Up @@ -3137,7 +3138,7 @@ public void start() {
processor.start(executor, compiler);
System.out.println("Starting scheduler...");
master.start(executor);
pluginManager.log("Shesmu started.", Map.of());
pluginManager.log("Shesmu started.", LogLevel.INFO, Map.of());
}

private <L, V> void storeEntries(ObjectNode entries, LabelledKeyValueCache<?, ?, ?> cache) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import ca.on.oicr.gsi.prometheus.LatencyHistogram;
import ca.on.oicr.gsi.shesmu.Server;
import ca.on.oicr.gsi.shesmu.core.input.shesmu.ShesmuIntrospectionValue;
import ca.on.oicr.gsi.shesmu.plugin.LogLevel;
import ca.on.oicr.gsi.shesmu.plugin.SourceLocation;
import ca.on.oicr.gsi.shesmu.plugin.SourceLocation.SourceLocationLinker;
import ca.on.oicr.gsi.shesmu.plugin.Utils;
Expand Down Expand Up @@ -769,7 +770,8 @@ public CommandStatistics command(
@Override
public Boolean accepted() {
labels.put("command", c.command());
pluginManager.log("Performed command", labels);
pluginManager.log(
"Performed command", LogLevel.INFO, labels);
return true;
}

Expand All @@ -787,7 +789,8 @@ public Boolean murder(Filter filter) {
@Override
public Boolean purge() {
labels.put("command", c.command());
pluginManager.log("Performed command", labels);
pluginManager.log(
"Performed command", LogLevel.INFO, labels);
purge.add(e.getKey());
stateCount
.labels(
Expand All @@ -800,7 +803,8 @@ public Boolean purge() {
@Override
public Boolean reset() {
labels.put("command", c.command());
pluginManager.log("Performed command", labels);
pluginManager.log(
"Performed command", LogLevel.INFO, labels);
if (e.getValue().lastState != ActionState.UNKNOWN) {
stateCount
.labels(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,8 @@
import ca.on.oicr.gsi.shesmu.compiler.definitions.SignatureDefinition;
import ca.on.oicr.gsi.shesmu.compiler.definitions.SignatureVariableForDynamicSigner;
import ca.on.oicr.gsi.shesmu.compiler.definitions.SignatureVariableForStaticSigner;
import ca.on.oicr.gsi.shesmu.plugin.Definer;
import ca.on.oicr.gsi.shesmu.plugin.ErrorableStream;
import ca.on.oicr.gsi.shesmu.plugin.Parser;
import ca.on.oicr.gsi.shesmu.plugin.PluginFile;
import ca.on.oicr.gsi.shesmu.plugin.PluginFileType;
import ca.on.oicr.gsi.shesmu.plugin.RequiredServices;
import ca.on.oicr.gsi.shesmu.plugin.*;
import ca.on.oicr.gsi.shesmu.plugin.SourceLocation.SourceLocationLinker;
import ca.on.oicr.gsi.shesmu.plugin.SupplementaryInformation;
import ca.on.oicr.gsi.shesmu.plugin.Utils;
import ca.on.oicr.gsi.shesmu.plugin.action.Action;
import ca.on.oicr.gsi.shesmu.plugin.action.ActionState;
import ca.on.oicr.gsi.shesmu.plugin.action.CustomActionParameter;
Expand Down Expand Up @@ -851,11 +844,11 @@ public Stream<String> isOverloaded(Set<String> services) {
}

@Override
public void log(String message, Map<String, String> labels) {
public void log(String message, LogLevel level, Map<String, String> labels) {
final Map<String, String> amendedLabels = new TreeMap<>(labels);
amendedLabels.put("plugin", instance.fileName().toString());
amendedLabels.put("plugin_type", FormatTypeWrapper.this.fileFormat.getClass().toString());
PluginManager.this.log(message, amendedLabels);
PluginManager.this.log(message, level, amendedLabels);
}

public Stream<RefillerDefinition> refillers() {
Expand Down Expand Up @@ -1210,12 +1203,12 @@ public final Stream<ConfigurationSection> listConfiguration() {
return configuration.stream().map(FileWrapper::configuration);
}

public void log(String message, Map<String, String> attributes) {
fileFormat.writeLog(message, attributes);
public void log(String message, LogLevel level, Map<String, String> attributes) {
fileFormat.writeLog(message, level, attributes);
for (final var reference : this.wrappers.values()) {
final var wrapper = reference.get();
if (wrapper != null) {
wrapper.instance.writeLog(message, attributes);
wrapper.instance.writeLog(message, level, attributes);
}
}
}
Expand Down Expand Up @@ -2051,14 +2044,14 @@ public Stream<ConfigurationSection> listConfiguration() {
return formatTypes.stream().flatMap(FormatTypeWrapper::listConfiguration);
}

public void log(String message, Map<String, String> attributes) {
public void log(String message, LogLevel level, Map<String, String> attributes) {
if (LOG_REENTRANT_CHECK.get()) {
throw new IllegalStateException("Trying to log while logging.");
}
LOG_REENTRANT_CHECK.set(true);
try {
for (final var format : this.formatTypes) {
format.log(message, attributes);
format.log(message, level, attributes);
}
} finally {
LOG_REENTRANT_CHECK.set(false);
Expand Down

0 comments on commit 4e2e86c

Please sign in to comment.