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

[2.0] Implement the Scope and Hub of the unified API #679

Merged
merged 4 commits into from
Oct 29, 2018

Conversation

ste93cry
Copy link
Collaborator

Q A
Branch? 2.0
Bug fix? no
New feature? yes
BC breaks? yes
Deprecations? no
Tests pass? yes
License MIT

This PR aims at providing the Scope and Hub features of the unified SDK API. It's based on the work of @HazAT and improves it by adding all the needed docblocks and refactoring the code while improving at the same time the unit tests. There are a few inconsistencies of the API which I would like to discuss before merging:

  • the capture* methods of the Scope do not follow the same pattern for the function definition: some let you set the severity level of the event, others don't. Also there is no way to pass a customized payload to the client (see the Client::capture* methods to understand what I'm referring to)
  • the Scope class does not allows to set data on all contexts: runtime and server OS contexts are missing. Also the API of the scope doesn't expose the underlying context object which means that the methods developed to easy the management of the context data are not available to the end user.
  • the Hub::applyToEvent method behaves differently from data to data being merged into the event. As an example, the breadcrumbs are not merged with the existing ones but the severity level always override the one set in the event. Why?

@ste93cry ste93cry added this to the Release 2.0 milestone Oct 22, 2018
@ste93cry ste93cry requested review from HazAT and Jean85 October 22, 2018 20:32
@HazAT
Copy link
Member

HazAT commented Oct 23, 2018

When talking about capture* on the Scope you actually meant Hub, right?
So I know this is one of the bigger changes of the API. Before our capture* methods took a payload which can be anything the event takes?
While this maybe worked in PHP in other SDKs you were not able to pass anything here the event takes, only for example tags extra and so on, but not an exception with for example.

That's why we went with the approach to remove this "magic" payload parameter and introduced Hub::withScope and EventProcessors as a workaround for this.


If someone wants to change server or os context of an event, they should write their own integration or add an EventProcessor. We do not want to expose all possible getter/setter that is on the event. Instead, if someone wants to fundamentally modify the event they should, as said before an EventProcessor, an Integration or beforeSend callback.


Scope::applyToEvent wasn't just fully implemented by me, ultimately the Scope should be the single source of truth when it comes to the "State". Which means the current Scope holds all breadcrumbs, context data (most used) and EventProcessors. Before an event will be sent off to Sentry if should go through Scope::applyToEvent where we merge the "State" of the Scope onto the event.

src/State/Scope.php Show resolved Hide resolved
tests/State/LayerTest.php Show resolved Hide resolved
@ste93cry
Copy link
Collaborator Author

When talking about capture* on the Scope you actually meant Hub, right?
So I know this is one of the bigger changes of the API. Before our capture* methods took a payload which can be anything the event takes?
While this maybe worked in PHP in other SDKs you were not able to pass anything here the event takes, only for example tags extra and so on, but not an exception with for example.

That's why we went with the approach to remove this "magic" payload parameter and introduced Hub::withScope and EventProcessors as a workaround for this.

Yes, I indeed meant Hub. It's fine if you can't use anymore the payload, but the methods are inconsistent anyway because for example the captureMessage accepts a level argument but the captureException not. I think we should normalize them (and in case normalize the API across all SDKs). For the same reason you should use Hub::withScope or event processors to customize the data of the event you should in case use them to customize the level. Does it makes sense?

If someone wants to change server or os context of an event, they should write their own integration or add an EventProcessor. We do not want to expose all possible getter/setter that is on the event. Instead, if someone wants to fundamentally modify the event they should, as said before an EventProcessor, an Integration or beforeSend callback.

Even though I understand that exposing all the getters/setter of the event on the Scope object is out of discussion, on which base we decide that setTag and getTags are fine to be on the scope but not the getters/setters for the other contexts (this is just an example, I could have written the same thing for any property of the event)? Probably the unified API should also unify the way you interact with the event and should be consistent without putting half of the setters/getters on the scope and half on the event

Copy link
Collaborator

@Jean85 Jean85 left a comment

Choose a reason for hiding this comment

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

This is a grea PR! Great work with the tests too!

I've commented a few things here and there, but nothing major...

src/BreadcrumbErrorHandler.php Outdated Show resolved Hide resolved
src/Breadcrumbs/Breadcrumb.php Outdated Show resolved Hide resolved
src/Breadcrumbs/Breadcrumb.php Outdated Show resolved Hide resolved
src/Severity.php Outdated Show resolved Hide resolved
src/State/Hub.php Outdated Show resolved Hide resolved
src/State/Scope.php Outdated Show resolved Hide resolved
src/State/Scope.php Outdated Show resolved Hide resolved
tests/Context/AbstractContextTest.php Outdated Show resolved Hide resolved
tests/State/ScopeTest.php Outdated Show resolved Hide resolved
src/Severity.php Show resolved Hide resolved
@HazAT
Copy link
Member

HazAT commented Oct 23, 2018

@ste93cry The basic idea is that the use case for captureMessage is for "logging".
For logging, it makes sense to define the level easily since it would be really annoying to do

Sentry.withScope(function($scope) {
  $scope->setLevel(Severity::debug());
  Sentry.captureMessage("test");
});

vs.

Sentry.captureMessage("test", Severity::debug());

In general, we want that the simplest use case of the SDK doesn't need any deep knowledge about Sentry at all. That's why we removed all the payload and second "magic" args from all other capture* methods.

There is setLevel on the Scope if you ever want to change the Level when capturing an Exception with captureException.


The idea of the unified API is to abstract away the complexity of the Client and the Event behind the Hub / Scope.
We still want users to be able to just create a new Client, instead of calling init, but then they are responsible for managing the State by themselves. If someone wants to fundamentally change the payload they have to go through an EventProcessor.

@ste93cry
Copy link
Collaborator Author

Imho soon or later someone will start asking why on the scope there are some methods and not others... Also the API doesn't provide any way except having to use an event processor to remove a tag or any data from the contexts exposed by the scope. It seems to me that the API aims to be simple and this is good, but half of the things can be set in some way and the other half can't. As a user my first question would be on what basis those methods were chosen and not others.

@ste93cry ste93cry force-pushed the feature/hub-scope branch 2 times, most recently from bdc7dcb to 76984fa Compare October 23, 2018 21:17
@HazAT
Copy link
Member

HazAT commented Oct 24, 2018

@ste93cry So we decided on the public API what we think would be the most common use case for >90% of people using Sentry.
Most people install it, call init and that's it.
Maybe they set some Tags to filter or add extra data to have more context.

Just to elaborate on the advantages of small public API again:
We can easily change the internals of events and how we send them.

While we still wanted to maintain great flexibility if your usage of our SDK isn't the norm, it's fine, we want users to have ways around our limited public API but we will not deliver guarantees that the internal will work like this in a future version of our SDK.

The Public API we deliver is a contract we tend to keep, but if we someday decide for example to completely drop the OS Context (not that we actually want to do this) from the event and people where using setOSContext across all SDKs, we have to update all SDKs to be on par with our decision.

Ultimately it's about the smaller the public documented API the less maintenance we have to do.
We can always add more things later but then we do that in all SDKs.

@Jean85
Copy link
Collaborator

Jean85 commented Oct 24, 2018

@HazAT we should probably state this (maybe concisely) on the README to clarify what's covered and considered as public API, in relation to BC and semantic versioning then.

@ste93cry ste93cry force-pushed the feature/hub-scope branch 2 times, most recently from cb04813 to 462cf21 Compare October 25, 2018 14:31
Copy link
Member

@HazAT HazAT left a comment

Choose a reason for hiding this comment

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

Great work so far, there are a few minor things but we will change them in the upcoming PRs. 🥇

Copy link
Collaborator

@Jean85 Jean85 left a comment

Choose a reason for hiding this comment

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

LGTM! 👍
I have added a few questions, but non are blockers for the merge.

src/Breadcrumbs/MonologHandler.php Show resolved Hide resolved
src/Client.php Show resolved Hide resolved
src/Severity.php Outdated Show resolved Hide resolved
src/State/Hub.php Outdated Show resolved Hide resolved
@ste93cry ste93cry force-pushed the feature/hub-scope branch 2 times, most recently from f3050e7 to 414afdf Compare October 26, 2018 15:59
@ste93cry ste93cry requested review from Jean85 and HazAT October 26, 2018 16:08
Copy link
Collaborator

@Jean85 Jean85 left a comment

Choose a reason for hiding this comment

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

Only one minor PHPDoc fix, LGTM 👍

src/State/Hub.php Outdated Show resolved Hide resolved
Copy link
Member

@HazAT HazAT left a comment

Choose a reason for hiding this comment

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

Solid PR, there are some minor things we iron out in the PRs to come, no blocker.

@ste93cry ste93cry merged commit 00e5d08 into getsentry:2.0 Oct 29, 2018
@ste93cry ste93cry deleted the feature/hub-scope branch October 29, 2018 09:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants