Skip to content
This repository was archived by the owner on Aug 30, 2023. It is now read-only.

Conversation

@maciejwalkowiak
Copy link
Contributor

📢 Type of change

  • Bugfix
  • New feature
  • Enhancement
  • Refactoring

📜 Description

Added SentryAppender that converts Logback events into Sentry events and sends them to Sentry.

💚 How did you test it?

I added Sample project using Logback, there is also an integration test. On the side I have a POC of Sentry + Logback + Spring Boot integration - https://github.com/maciejwalkowiak/sentry-spring-boot-demo

📝 Checklist

  • I reviewed submitted code
  • I added tests to verify changes
  • All tests passing
  • No breaking changes

}

dependencies {
implementation(project(":sentry-core"))
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@marandaneto I am not 100% sure about scope of these dependencies.

Copy link
Contributor

@marandaneto marandaneto Aug 12, 2020

Choose a reason for hiding this comment

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

the timber integration has it as an api instead of implementation because one may configure events and breadcrumbs min level (SentryLevel is bundled in sentry-core), so the client needs access to sentry-core classes, if in this case, they dont need to access any of the Sentry classes that are bundled in sentry-core, then implementation is fine

Copy link
Member

Choose a reason for hiding this comment

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

Wouldn't we document that users using logback can add only this package and get the whole Sentry.X API?
Otherwise users would need to make sure they bump both sentry-core and sentry-logback while keeping them compatible.

I believe it would make sense to have all the transient package's API show up. So api like the timber makes sense?

Copy link
Member

@bruno-garcia bruno-garcia left a comment

Choose a reason for hiding this comment

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

First pass (need to continue later)

implementation(project(":sentry-logback"))
implementation(project(":sentry-core"))
implementation(Config.Libs.logbackClassic)
implementation(Config.Libs.logbackCore)
Copy link
Member

Choose a reason for hiding this comment

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

Curious: does classic depend on core or the other way around? I that case we could drop one of them and pin a single dep if transient flows through


@Override
public void start() {
if (dsn != null) {
Copy link
Member

Choose a reason for hiding this comment

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

We need some config here to allow a user to opt out for initializing thought the sdk.

It's confusing when the 3 integrations are on and folks don't know what is initing it.

If we can also check if the sdk is already initializing and then warn about it. (Like Sentry.isEnabled) would be best. Last init wins is OK so dispose previous bound hub l/Clientand get it init again ur it's often a mistake.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Passing config here is optional. If user has at the same time Spring Boot starter.and configures Sentry through it he can omit completely passing options through Logback

Copy link
Member

Choose a reason for hiding this comment

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

I see. Though there's no way to avoid initializing the SDK via this integration, right?
So if a user adds the dsn to the appender configuration file, it will init the SDK even if it was already initialized.

That's why the suggestion:

If we can also check if the sdk is already initializing and then warn about it. (Like Sentry.isEnabled) would be best. Last init wins is OK so dispose previous bound hub l/Clientand get it init again ur it's often a mistake.

Or at least log a warning with the diagnostic logger

@bruno-garcia
Copy link
Member

BTW super excited to see this landing!! Thanks a lot

@marandaneto
Copy link
Contributor

BTW super excited to see this landing!! Thanks a lot

yep, left a few comments but pretty excited as well, thanks!

}

for (Map.Entry<String, String> entry : loggingEvent.getMDCPropertyMap().entrySet()) {
event.setTag(entry.getKey(), entry.getValue());
Copy link
Contributor

Choose a reason for hiding this comment

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

just wondering if we should do setTag(x, y) or setExtras(x, y) or event.setContexts.out(x, y), because getMDCPropertyMap means map diagnostic context, the old version add as a tag so maybe we should keep as it is to keep compatibility

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think you mean that old version adds as extras? I see that in old SDK there was an option to tell Sentry which MDC tags qualify as tag and which as extra. In 2.0 it's not there anymore so we can either add it or pick tags or extras I think

Copy link
Contributor

Choose a reason for hiding this comment

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

yeah its trick: https://github.com/getsentry/sentry-java/blob/master/sentry-logback/src/main/java/io/sentry/logback/SentryAppender.java#L172-L178
I'd suggest then to use setExtras instead of setTag, wdyt?
I don't think we need this configuration to choose when its a tag or not, at least not in the 1st version.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

What's exactly the difference in practice between tags and extras? I see that they are presented differently and users can filter issues by tags. Extras are just metadata attached to an event but users can't do anything with it. Am I correct?

Copy link
Contributor

Choose a reason for hiding this comment

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

yes, exactly, and looks like getMDCPropertyMap returns only metadata as well

Copy link
Contributor Author

Choose a reason for hiding this comment

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

But without the ability to search by this metadata its usage is very limited. I imagine users may want to put a userId to MDC and expect to search events for specific user.

Perhaps it makes sense to add a property to SentryAppender mdcTags - similar to get the same functionality as in Sentry SDK 1.x without cluttering sentry-core?

Copy link
Contributor

Choose a reason for hiding this comment

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

I get your point, for user for example, our protocol has a dedicated field, but with this integration, it'd be hard to know which key is user-related.
I'd say we can start with everything being an extra and improve from there when we get feedback.
@bruno-garcia opinions?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok I set it as extras 👍

Copy link
Contributor

@marandaneto marandaneto left a comment

Choose a reason for hiding this comment

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

LGTM

}

dependencies {
implementation(project(":sentry-core"))
Copy link
Member

Choose a reason for hiding this comment

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

Wouldn't we document that users using logback can add only this package and get the whole Sentry.X API?
Otherwise users would need to make sure they bump both sentry-core and sentry-logback while keeping them compatible.

I believe it would make sense to have all the transient package's API show up. So api like the timber makes sense?


@Override
public void start() {
if (dsn != null) {
Copy link
Member

Choose a reason for hiding this comment

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

I see. Though there's no way to avoid initializing the SDK via this integration, right?
So if a user adds the dsn to the appender configuration file, it will init the SDK even if it was already initialized.

That's why the suggestion:

If we can also check if the sdk is already initializing and then warn about it. (Like Sentry.isEnabled) would be best. Last init wins is OK so dispose previous bound hub l/Clientand get it init again ur it's often a mistake.

Or at least log a warning with the diagnostic logger

* @param loggingEvent the logback event
* @return the sentry event
*/
@SuppressWarnings("JdkObsolete")
Copy link
Member

Choose a reason for hiding this comment

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

Why do we need this suppress? Maybe a note will help folks reading the code

Suggested change
@SuppressWarnings("JdkObsolete")
// Ignoring the obsolete because .... ?
@SuppressWarnings("JdkObsolete")

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Because we're using java.util.Date and error prone forbids using this class. Ideally we should avoid using this class but I believe we do use it because newer Date classes are not supported on Android.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Or at least log a warning with the diagnostic logger

We cannot access diagnostic logger from this level as it's a part of SentryOptions. Perhaps we should add this check isSentryEnabled and log warning inside Sentry.init() itself?

Copy link
Member

Choose a reason for hiding this comment

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

re: Obsolete. That description you gave here would fit well as a comment. So it's clear why we ignored it.

re: logger. Sounds good to at least log on sentry.init!

Copy link
Member

@bruno-garcia bruno-garcia left a comment

Choose a reason for hiding this comment

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

LGTM already. The Threads stuff could be a new PR if at all

event.setThrowable(throwableInformation.getThrowable());
}

if (loggingEvent.getThreadName() != null) {
Copy link
Member

Choose a reason for hiding this comment

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

what about we add a single thread to the list then? with id, name? When the attachThreads is false that is

@bruno-garcia bruno-garcia merged commit d18da36 into feat/sentry-java Aug 20, 2020
@bruno-garcia bruno-garcia deleted the sentry-java-logback branch August 20, 2020 01:29
maciejwalkowiak added a commit to maciejwalkowiak/sentry-android that referenced this pull request Aug 30, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants