question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Provide a way to perform additional work in `Logging{Client,Service}`

See original GitHub issue

For example, a user may have some MDC property he or she wants to be logged. To make the current MDC property is transferred to the moment where Logging{Client,Service} logs something, a user has to:

  1. Store the current thread’s MDC property somewhere, e.g. local variable.
  2. When Logging{Client,Service} logs something, load the property from (1) and set it to an MDC property.
  3. After logging is done, the MDC property set in (2) has to be cleared or reverted to the old value.

To make this possible, we need to allow a user specify some custom logic which is executed when:

  • Logging{Client.execute,Service.serve}() is called, for the step 1.
  • Before and after logging, for the step 2 and 3.

I’m not really sure if you need to allow running an arbitrary logic, though. It may be just enough to let a user specify a list of MDC keys, so they are stored and loaded automatically. Thoughts?

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:18 (7 by maintainers)

github_iconTop GitHub Comments

2reactions
trustincommented, May 15, 2020

I wonder if it’s a good idea to add some common hooks API for RequestContextStorage, e.g. RequestContextStorage.hook(Function<RequestContextStorage, RequestContextStorage>)

I tried this but I wasn’t sure I’m going into the right direction because:

  • When MDC properties are captured is limited to when a context is pushed. A user might want to copy an MDC property after ctx.push(), especially for the server side (but not limited to the server side - imagine you write a client-side decorator). He or she might also want to update the captured MDC property:
    // This will be captured by ctx.push() below:
    MDC.put("foo", "1234");
    try (ignored = ctx.push()) {
        // But there's no way to capture this:
        MDC.push("txid", "1234");
        // ... situation has changed ...
        // But there's no way to update the captured value:
        MDC.put("foo", "5678");
    }
    
  • What we have to do when a context is popped is ambiguous and sometimes hard to reason.
  • It’s hard to handle the nested contexts such as the following. Although not impossible, I’m not sure it’s worth the complexity.
    try (ignored = sctx.push()) {
      try (ignored = cctx.push()) {
        try (ignored = sctx.push()) {
          try (ignored = cctx.push()) {
            try (ignored = sctx.push()) { ... }
          }
        }
      }
    }
    

Therefore, I came back to the idea at https://github.com/line/armeria/issues/2634#issuecomment-625637235

The initial feedback from @anuraaga was that it’s not a good idea to add another API similar to the current attribute API. Then how about not providing such API in RequestContext but in a separate utility class? e.g.

public class RequestScopedMdc { // We provide this class.
  private static final AttributeKey<Map<String, String>> MDC_ATTR_KEY = ...;

  static {
    // Intercept MDC operations.
    MDC.mdcAdapter = new OurMdcAdapterImpl(MDC.mdcAdapter);
  }

  public static void import(String prop, RequestContext ctx) {
    ctx.attr(MDC_ATTR_KEY).put(prop, MDC.get(prop));
  }
}

// User code:
MDC.put("txid", "1234");
...
try (ignorable = Clients.withContextCustomizer(ctx -> {
    RequestScopedMdc.import("txid", ctx);
    // or
    RequestScopedMdc.importAll(ctx);
    // Note: A user can write a decorator to remove the need for
    //       withContextCustomizer().
})) {
    client.execute(...);
}

// Later in another thread:
assert MDC.get("txid") == null;
try (ignored = ctx.push()) {
  // Now fetched from thread-local context's MDC_ATTR_KEY attr:
  assert MDC.get("txid").equals("1234"); 
}
// thread-local context has been popped, so 'txid' is gone:
assert MDC.get("txid") == null;

This is better than the previous idea because:

  • It doesn’t add anything to RequestContext API. Just one utility class.
  • A user doesn’t have to modify Logback configuration, which can take too much for a client-only user who seeks for a less invasive solution.
0reactions
trustincommented, May 19, 2020

Thanks everyone for valuable feed back ❤️

Read more comments on GitHub >

github_iconTop Results From Across the Web

Logging client libraries | Google Cloud
Logs consist of individual log entries in structured format, with fields like resource , sourceLocation , labels , and trace that give additional...
Read more >
How to Successfully Implement & the Benefits of Customer ...
How to Successfully Implement Customer Logging · Develop a process for providing superior service to Web submissions. · Market your new service to...
Read more >
Logging - Ads API - Google Developers
Logging and monitoring work in tandem to help you understand and optimize application performance, as well as to diagnose errors and system-related issues....
Read more >
Logging and diagnostics in ASP.NET Core SignalR
To get logs from the .NET client, you can use the ConfigureLogging method on HubConnectionBuilder . This works the same way as the ......
Read more >
Logging Overview - Oracle Help Center
Logging provides access to logs from Oracle Cloud Infrastructure resources. These logs include critical diagnostic information that describes how resources ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found