Fork me on GitHub
#observability
<
2022-08-22
>
emccue00:08:02

@bruno.bonacci Don't know if this is something that would interest you, but i've taken a very https://www.youtube.com/watch?v=WhwqBUCYQO0 approach and am attempting to rip off mulog https://github.com/bowbahdoe/log

bruno.bonacci09:08:48

That's great, I was thinking to add a Java client as well. I'm just so short with the time at the moment. Let me know how you are proceeding with it and if you are facing any challenges.

emccue00:08:28

One "choice" I made I feel weird about is keeping log levels around

emccue00:08:02

it is just another type of metadata but 🤷

emccue00:08:40

And i'm punting on the ring buffer stuff since idk how to implement that without a dependency

emccue21:08:40

...tempted but idk the difference between this and the persistent ring buffer

bruno.bonacci09:08:22

the disruptor is a nice project, be careful about what you add in your core project as the more you add the more possibility of version conflict with other (direct or transitive) dependencies. The nice thing about the persistent/immutable ring-buffer I use is that being immutable it removes a ton of possible concurrency issues. The disruptor is designed for concurrent use as well, but you have to follow its model very closely.

emccue16:08:04

The only thing (I think) stopping this from being able to be used as a frontend to mulog is the context system

emccue16:08:18

I am currently storing all the context for a call like so

emccue16:08:55

private static final AtomicReference<ThreadLocal<Context>> CONTEXT_REFERENCE =
            new AtomicReference<>(ThreadLocal.withInitial(() -> Context.Global.EMPTY));
public sealed interface Context {
        record Global(List<Log.Entry> entries) implements Context {
            static final Global EMPTY = new Global(List.of());
        }

        record Child(
                @Design(Design.Choice.EVERY_CHILD_CONTEXT_ELEMENT_HAS_ITS_OWN_REFERENCE_TO_A_THREAD)
                Thread thread,
                Instant timestamp,
                Flake flake,
                List<Log.Entry> entries,
                Context parent
        ) implements Context {
        }
    }

emccue16:08:55

which isn't too dissimilar from mulog's approach

(defonce ^{:doc "The global logging context is used to add properties
             which are valid for all subsequent log events.  This is
             typically set once at the beginning of the process with
             information like the app-name, version, environment, the
             pid and other similar info."}
  global-context (atom {}))



(def ^{:doc "The local context is local to the current thread,
             therefore all the subsequent call to log withing the
             given context will have the properties added as well. It
             is typically used to add information regarding the
             current processing in the current thread. For example
             who is the user issuing the request and so on."}
  local-context (ut/thread-local nil))

emccue16:08:41

just they aren't the same context - and making a "context provider" feels gross

emccue16:08:56

+ I am being more restrictive in terms of data allowed in events. Fine flowing from this -> mulog, hard to handle if context from mulog flows -> this