- void log(ThinLogger logger, Level level, ResourceBundle bundle, String msg, Throwable thrown, Instant instant,
- StackTraceElement callLocation) {
- ThinLogEntry logEntry = new ThinLogEntry(logger, level, msg, instant, thrown, callLocation);
- submit(logEntry);
+ private void log(ThinLogger logger, Level level, ResourceBundle bundle, String msg, Instant instant,
+ Thread thread, Throwable thrown, StackTraceElement callLocation) {
+ assert level != null;
+ assert logger != null;
+ assert msg != null;
+ assert instant != null;
+ assert thread != null;
+
+ final long sequence = nextEntry.incrementAndGet();
+
+ Map<String, Serializable> logEntry = new LogEntryMap(sequence);
+
+ // same object as key class name
+ logEntry.put(KEY_LEVEL, level);
+ logEntry.put(KEY_MSG, msg);
+ logEntry.put(KEY_INSTANT, instant);
+ if (thrown != null)
+ logEntry.put(KEY_THROWABLE, thrown);
+ if (callLocation != null)
+ logEntry.put(KEY_CALL_LOCATION, callLocation);
+
+ // object is a string
+ logEntry.put(KEY_LOGGER, logger.getName());
+ logEntry.put(KEY_THREAD, thread.getName());
+
+ // should be unmodifiable for security reasons
+ if (!isClosed())
+ submit(Collections.unmodifiableMap(logEntry));
+ }
+
+ }
+
+ /**
+ * An internal optimisation for collections. It should not be referred to
+ * directly as a type.
+ */
+ // TODO optimise memory with a custom map implementation?
+ // but access may be slower
+ private static class LogEntryMap extends HashMap<String, Serializable> {
+ private static final long serialVersionUID = 7361434381922521356L;
+
+ private final long sequence;
+
+ private LogEntryMap(long sequence) {
+ // maximum 7 fields, so using default load factor 0.75
+ // an initial size of 10 should prevent rehashing (7 / 0.75 ~ 9.333)
+ // see HashMap class description for more details
+ super(10, 0.75f);
+ this.sequence = sequence;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o instanceof LogEntryMap)
+ return sequence == ((LogEntryMap) o).sequence;
+ else if (o instanceof Map) {
+ Map<?, ?> map = (Map<?, ?>) o;
+ return get(KEY_INSTANT).equals(map.get(KEY_INSTANT)) && get(KEY_THREAD).equals(map.get(KEY_THREAD));
+ } else
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return (int) sequence;