getsentry / getsentry/sentry-java

Add `scope.SetEnvironment`

未关闭
#5,769 1 条评论 0 个 reaction 已指派 1 人 已被 @bitsandfoxes 认领 在 GitHub 查看
Feature Java Platform: Java
主要语言
Kotlin
星标
1.4k
派生
478
平均合并
2 天 23 小时
30 天内合并 PR
67

描述

# Proposal: Allow setting `Environment` on the Scope

Unblocks
- https://github.com/getsentry/sentry-dotnet/issues/5387
- https://github.com/getsentry/sentry-unity/pull/2764

## Summary

Add `getEnvironment()` / `setEnvironment(String)` to sentry-java's `IScope`, so other SDKs (hybrid SDKs like .NET, Godot, Unity, Unreal, React Native?) and end users can set the `Environment` on the scope at runtime. This lifts the restriction of having to provide it strictly at init via `SentryOptions.setEnvironment(...)`.

This brings `sentry-java` to parity with `sentry-cocoa` and `sentry-native`. These already expose a scope-/runtime-level environment setter.

## Motivation

Today `environment` in sentry-java lives only on `SentryOptions`, fixed at init time. Any hybrid SDKs layered on top either manage their own `environment` or provide a way for users to modify it at runtime. This creates the need to sync it into the Java layer at runtime. That way events, and persisted (background/ANR/NDK) events, carry the correct value.

Both reference SDKs already support this:

| SDK | API | Level | Getter? |
|--------|--------------------------------------------------------------|--------------|---------|
| cocoa | `- (void)setEnvironment:(NSString *)environment` on `Scope` | scope | no |
| native | `sentry_set_environment(const char *environment)` (+ `_n`) | global scope | no |
| java | **(proposed)** `IScope.setEnvironment(String)` + `getEnvironment()` | scope | yes |

## Proposed API (sentry-java)

```java
public interface IScope {
// ...
@Nullable String getEnvironment();

/**
* Sets the Scope's environment. Takes precedence over SentryOptions#getEnvironment()
* when applied to events. Mainly used by hybrid SDKs to sync their environment.
*/
void setEnvironment(@Nullable String environment);
}
```

Reached by users/hybrid SDKs the same way as other scope mutations:

```java
Sentry.configureScope(scope -> scope.setEnvironment("staging"));
```

Unlike cocoa, we could also add a **getter**, consistent with other Java scope fields like `getTransactionName`, and `getUser` e.t.c. and required by the combined-scope view.

### API References

**sentry-cocoa**
- [`SentryScope.h`](https://github.com/getsentry/sentry-cocoa/blob/8693a8f07525287fcc3714cdbc505cf0b73b4d84/Sources/Sentry/Public/SentryScope.h#L99) - `(void)setEnvironment:(NSString *_Nullable)environment;`
- [`SentryScope.m`](https://github.com/getsentry/sentry-cocoa/blob/8693a8f07525287fcc3714cdbc505cf0b73b4d84/Sources/Sentry/SentryScope.m#L385) - sets `environmentString`, then notifies scope observers.
- [`SentryScope::applyToEvent`](https://github.com/getsentry/sentry-cocoa/blob/8693a8f07525287fcc3714cdbc505cf0b73b4d84/Sources/Sentry/SentryScope.m#L638-L643) - odering & backfill
- Usage: `SentrySDK.configureScope { $0.setEnvironment("staging") }`

**sentry-native**
- [`sentry.h`](https://github.com/getsentry/sentry-native/blob/2723a0fb5707ae8596e90ae041d397d8ce4e9ceb/include/sentry.h#L2272-L2278) - `SENTRY_API void sentry_set_environment(const char *environment);`
- [`sentry_core.c`](https://github.com/getsentry/sentry-native/blob/2723a0fb5707ae8596e90ae041d397d8ce4e9ceb/src/sentry_core.c#L935-L951) - overwrites `scope->environment`
- [`sentry__scope_apply_to_event`](https://github.com/getsentry/sentry-native/blob/2723a0fb5707ae8596e90ae041d397d8ce4e9ceb/src/sentry_scope.c#L449)
- Usage: `sentry_set_environment("staging");`

## Precedence of application

Effective order from top to bottom: "environment set on the event itself" > scope > options**

- `SentryClient.applyScope`: applies scope environment to the event only when the event has none.
- [`MainEventProcessor.setEnvironment`](https://github.com/getsentry/sentry-java/blob/20be537e26bae44a7ffdb1b207ea3f631a711a15/sentry/src/main/java/io/sentry/MainEventProcessor.java#L154-L158): later fallback to `options.getEnvironment()` when still unset

This matches the precedence used by `cocoa` and `native`.

## Known gap / suggested follow-up

The Android **AEI/ANR backfill** processor reads environment only from the *options* cache, not the *scope* cache:

- [`ApplicationExitInfoEventProcessor.setEnvironment`](https://github.com/getsentry/sentry-java/blob/20be537e26bae44a7ffdb1b207ea3f631a711a15/sentry-android-core/src/main/java/io/sentry/android/core/ApplicationExitInfoEventProcessor.java#L461-L466) reads `PersistingOptionsObserver.ENVIRONMENT_FILENAME`, falling back to `options.getEnvironment()`:

So a scope-set environment is persisted (via the new `PersistingScopeObserver` file) but is **not** picked up when backfilling exit-info events.
This could be resolved by reading the scope file first?

贡献指南

打开贡献指南

评估

这个 Issue 还没有评估数据。

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。