observability

emccue 2022-08-22T00:50:02.862229Z

@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

2022-08-22T09:40:48.585919Z

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.

emccue 2022-08-23T00:07:28.566349Z

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

emccue 2022-08-23T00:08:02.677569Z

it is just another type of metadata but 🤷

emccue 2022-08-23T00:08:40.633679Z

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

2022-08-25T09:25:22.340389Z

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.

emccue 2022-08-25T16:06:04.422609Z

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

emccue 2022-08-25T16:06:18.573299Z

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

emccue 2022-08-25T16:06:55.842329Z

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 {
        }
    }

emccue 2022-08-25T16:07:55.819299Z

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))

emccue 2022-08-25T16:08:41.708509Z

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

emccue 2022-08-25T16:09:56.444549Z

+ 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

emccue 2022-08-24T21:19:40.074479Z

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