Skip to content

Commit

Permalink
Pending Audit Logs are sent in batches (#10918)
Browse files Browse the repository at this point in the history
  • Loading branch information
radeusgd authored Aug 30, 2024
1 parent 54dc0d0 commit 50325b6
Show file tree
Hide file tree
Showing 15 changed files with 451 additions and 147 deletions.
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import project.Any.Any
import project.Data.Json.JS_Object
import project.Data.Text.Text
import project.Errors.Illegal_Argument.Illegal_Argument
import project.Nothing.Nothing
import project.Panic.Panic
from project.Data.Boolean import Boolean, False, True

polyglot java import org.enso.base.enso_cloud.audit.AuditLog
polyglot java import org.enso.base.enso_cloud.audit.AuditLog.AuditLogError

## PRIVATE
type Audit_Log
Expand All @@ -21,6 +24,10 @@ type Audit_Log
automatically.
- async: Whether to submit the event asynchronously.
Defaults to True.
If `async` is True, the operation returns immediately. There is no way
to know if the log message was successfully submitted.
If `async` is False, the operation blocks until the log message is
successfully submitted, and will raise a panic if submitting fails.

? Restricted Fields

Expand All @@ -32,7 +39,19 @@ type Audit_Log
- `projectName`
- `projectSessionId`
report_event event_type:Text message:Text (metadata:JS_Object = JS_Object.from_pairs []) (async : Boolean = True) -> Nothing =
Illegal_Argument.handle_java_exception <|
Illegal_Argument.handle_java_exception <| Audit_Log_Error.handle_java_exception <|
case async of
True -> AuditLog.logAsync event_type message metadata.object_node
False -> AuditLog.logSynchronously event_type message metadata.object_node

## PRIVATE
type Audit_Log_Error
## PRIVATE
Error message:Text cause:Any

## PRIVATE
handle_java_exception =
on_error caught_panic =
cause = caught_panic.payload
Panic.throw (Audit_Log_Error.Error cause.getMessage cause)
Panic.catch AuditLogError handler=on_error
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public class HttpDownloaderTest {
@BeforeClass
public static void initServer() throws URISyntaxException, IOException {
serverExecutor = Executors.newSingleThreadExecutor();
server = HTTPTestHelperServer.createServer("localhost", port, serverExecutor, false);
server = HTTPTestHelperServer.createServer("localhost", port, serverExecutor, false, null);
server.addHandler("/texts", new TextHandler());
server.addHandler("/redirect", new RedirectHandler());
server.addHandler("/files", new BigFileHandler());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.enso.base.enso_cloud;

import org.enso.base.Environment_Utils;
import org.enso.base.enso_cloud.audit.AuditLog;

public final class CloudAPI {
/**
Expand Down Expand Up @@ -38,5 +39,6 @@ public static void flushCloudCaches() {
CloudRequestCache.clear();
AuthenticationProvider.reset();
EnsoSecretReader.flushCache();
AuditLog.resetCache();
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,42 @@
package org.enso.base.enso_cloud.audit;

import com.fasterxml.jackson.databind.node.ObjectNode;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

/**
* The high-level API for logging audit events.
*
* <p>The messages are sent on a single background thread in batches, but also as soon as possible.
* That means that we are never waiting for more messages to be batched to avoid delaying logs.
* However, if sending the previous batch took enough time that many messages have been scheduled in
* the meantime, all waiting messages (up to some limit) will be sent in a single request.
*/
public final class AuditLog {
/** Schedules the log message to be sent in the next batch, and returns immediately. */
public static void logAsync(String type, String message, ObjectNode metadata) {
var event = new AuditLogMessage(type, message, metadata);
AuditLogAPI.INSTANCE.logAsync(event);
AuditLogApiAccess.INSTANCE.logWithoutConfirmation(event);
}

/** Schedules the log message to be sent in the next batch, and waits until it has been sent. */
public static void logSynchronously(String type, String message, ObjectNode metadata) {
var event = new AuditLogMessage(type, message, metadata);
AuditLogAPI.INSTANCE.logSync(event);
Future<Void> future = AuditLogApiAccess.INSTANCE.logWithConfirmation(event);
try {
future.get();
} catch (ExecutionException | InterruptedException e) {
throw new AuditLogError("Failed to send log message: " + e, e);
}
}

public static class AuditLogError extends RuntimeException {
public AuditLogError(String message, Throwable cause) {
super(message, cause);
}
}

public static void resetCache() {
AuditLogApiAccess.INSTANCE.resetCache();
}
}

This file was deleted.

Loading

0 comments on commit 50325b6

Please sign in to comment.