Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Logback integration which exports context properties to MDC #305

Merged
merged 1 commit into from
Oct 21, 2016

Conversation

trustin
Copy link
Member

@trustin trustin commented Oct 14, 2016

  • Add RequestContextExportingAppender
  • Deprecate ServiceRequestContext.logger() and its related configuration
    properties

@trustin
Copy link
Member Author

trustin commented Oct 14, 2016

  • See testXmlConfig.xml for an example configuration.
  • See BuiltInProperty for the complete list of built-in properties
  • You can export any attributes and http headers as well (see testXmlConfig.xml again.)

@trustin
Copy link
Member Author

trustin commented Oct 14, 2016

@taicki @imasahiro PTAL

authority = authority.substring(0, m.start());
}
REQ_AUTHORITY.set(authority);
return;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this

Copy link
Member

@imasahiro imasahiro Oct 14, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oops, never mind.

}
}

String authority;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add final

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. Fixed. :-)

*/
protected abstract Channel channel();

@Override
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to put @Nullable annotation here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

return ch != null ? (A) ch.remoteAddress() : null;
}

@Override
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

return;
}

if (mdcKey.startsWith("req.http_headers.")) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about define string constant and use it?
mdcKey.substring(17) is hard to understand for me.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for suggestion. Fixed.


public Map<AttributeKey<?>, String> getAttributes() {
return Collections.unmodifiableMap(attrNames.entrySet().stream().collect(
Collectors.toMap(Entry::getKey, e -> e.getValue().substring(6))));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PREFIX_ATTRS.length() I think

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. Missed that one! :-)

import io.netty.util.AsciiString;
import io.netty.util.AttributeKey;

public class RequestContextExportingAppender extends UnsynchronizedAppenderBase<ILoggingEvent>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is Unsynchronized, do we need to make this class threadsafe (e.g. ConcurrentHashMap, computeIfAbsent)?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will make the export list immutable once start() is called.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Thanks for an advice.

if (enabledBuiltIns.contains(SSL_SESSION_ID)) {
final byte[] id = s.getId();
if (id != null) {
SSL_SESSION_ID.set(BaseEncoding.base16().lowerCase().encode(id));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can store BaseEncoding.base16().lowerCase() to a static final

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

@codecov-io
Copy link

codecov-io commented Oct 17, 2016

Current coverage is 64.35% (diff: 70.48%)

Merging #305 into master will increase coverage by 0.35%

@@             master       #305   diff @@
==========================================
  Files           310        316     +6   
  Lines         12236      12727   +491   
  Methods           0          0          
  Messages          0          0          
  Branches       1790       1906   +116   
==========================================
+ Hits           7830       8190   +360   
- Misses         3584       3661    +77   
- Partials        822        876    +54   

Powered by Codecov. Last update 1e6b034...94c0464

private RequestContextExporter exporter;

private final AppenderAttachableImpl<ILoggingEvent> aai = new AppenderAttachableImpl<>();
private final Set<BuiltInProperty> builtIns = EnumSet.noneOf(BuiltInProperty.class);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about making these part of a RequestContextExporterBuilder which returns RequestContextExporter after calling build()? It's a bit weird having this now-"temporary" state on the appender.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We cannot fix the mutability of appender because XML configuration requires it to be so - it has to call setExport() on each <export/> element. Please let me know if there's a way to build an immutable appender using Joran.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree the class won't be completely immutable, but at least wrapping these into a separate, Builder type of object, makes it clearer they're only used during setup.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK. Extracted intermediary data structure to RequestContextExporterBuilder. Looking better?

@trustin
Copy link
Member Author

trustin commented Oct 18, 2016

Found a bug where the exported MDC properties are not included in the Map returned by LoggingEvent.getMDCPropertyMap() when RequestContextExportingAppender is not the first appender in the appender list of a Logger. Will fix with non-trivial changes.

@trustin
Copy link
Member Author

trustin commented Oct 19, 2016

Bug fixed at: 3f918fd

Copy link
Contributor

@taicki taicki left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. A couple of minor comments.

return state;
}

private static int flag(RequestLog req, ResponseLog res) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: defining an enum and adding this method would be a bit more readable.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now using enum :-)

<export>remote.port</export>
<export>tls.cipher</export>
<export>req.http_headers.user-agent</export>
<export>attrs.req_id:com.example.RequestId#ATTR</export>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add an example in the above pattern for attrs' case.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated the documentation.

@trustin trustin force-pushed the logback branch 2 times, most recently from f9250fa to 085b9e7 Compare October 20, 2016 08:24
- Add RequestContextExportingAppender
- Deprecate ServiceRequestContext.logger() and its related configuration
  properties
Copy link
Contributor

@taicki taicki left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@taicki taicki merged commit 7e988af into line:master Oct 21, 2016
@trustin trustin deleted the logback branch October 21, 2016 01:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants