1 package org.simantics.audit.client;
3 import java.util.Arrays;
4 import java.util.HashMap;
9 import org.simantics.audit.AuditLogging;
10 import org.simantics.audit.AuditLogging.Level;
11 import org.simantics.audit.AuditLoggingException;
12 import org.slf4j.Logger;
13 import org.slf4j.LoggerFactory;
15 public class AuditLoggingClient {
17 private static final String AUDIT_SERVER_ADDRESS = "org.simantics.audit.serverAddress";
18 private static final String AUDIT_CLIENT_ID = "org.simantics.audit.clientId";
20 private static final Logger LOGGER = LoggerFactory.getLogger(AuditLoggingClient.class);
22 private static AuditLoggingClient INSTANCE;
24 private AuditLoggingAPIClient apiClient;
26 private AuditLoggingClient(String clientId, String serverAddress) throws AuditLoggingException {
27 apiClient = new AuditLoggingAPIClient(clientId, serverAddress);
30 private static AuditLoggingClient fromEnv() throws AuditLoggingException {
31 return fromProps(System.getProperties());
35 public static AuditLoggingClient fromProps(Map<Object, Object> properties) throws AuditLoggingException {
36 if (INSTANCE == null) {
37 synchronized (AuditLoggingClient.class) {
38 if (INSTANCE == null) {
39 String serverAddress = (String) properties.get(AUDIT_SERVER_ADDRESS);
40 String clientId = (String) properties.get(AUDIT_CLIENT_ID);
41 if (clientId == null || clientId.isEmpty())
42 clientId = UUID.randomUUID().toString();
43 if (serverAddress != null && !serverAddress.isEmpty()) {
44 INSTANCE = new AuditLoggingClient(clientId, serverAddress);
46 LOGGER.warn("No {} system property defined so client not configured", AUDIT_SERVER_ADDRESS);
54 public static String getUUID() throws AuditLoggingException {
55 return fromEnv().apiClient.getUuid();
58 public static void sendLog(List<Object> keyValues) throws AuditLoggingException {
59 commit(Level.INFO, toMap(keyValues.toArray()));
62 private static Map<String, Object> toMap(Object... keyValues) {
63 if ((keyValues.length % 2) != 0)
64 throw new IllegalArgumentException("Invalid amount of arguments! " + Arrays.toString(keyValues));
65 Map<String, Object> results = new HashMap<>(keyValues.length / 2);
66 for (int i = 0; i < keyValues.length; i += 2) {
67 Object key = keyValues[i];
68 Object value = keyValues[i + 1];
69 if (!(key instanceof String))
70 throw new IllegalArgumentException("Key with index " + i + " is not String");
71 results.put((String) key, value);
76 public static void sendLog(Map<String, Object> event) throws AuditLoggingException {
77 commit(Level.INFO, event);
80 public static void sendError(Map<String, Object> event) throws AuditLoggingException {
81 commit(Level.ERROR, event);
84 public static void sendError(List<Object> keyValues) throws AuditLoggingException {
85 commit(Level.ERROR, toMap(keyValues.toArray()));
88 public static void sendTrace(Map<String, Object> event) throws AuditLoggingException {
89 commit(Level.TRACE, event);
92 public static void sendTrace(List<Object> keyValues) throws AuditLoggingException {
93 commit(Level.TRACE, toMap(keyValues.toArray()));
96 private static void commit(Level level, Map<String, Object> message) throws AuditLoggingException {
98 AuditLoggingClient client = fromEnv();
99 if (client == null || client.apiClient == null) {
100 // No can do - at least log to file
101 LOGGER.warn("Audit logging server not configured - printing event to log");
102 LOGGER.info(message.toString());
104 AuditLoggingAPIClient apiClient = client.apiClient;
107 apiClient.log(message);
110 apiClient.error(message);
113 apiClient.trace(message);
119 } catch (AuditLoggingException e) {
120 // Just for debugging purposes
121 LOGGER.error("Could not send audit event {} with level {}", message, level, e);
122 // log this locally to a file just in case
123 AuditLogging.log("local", message);