sentry-dotnet icon indicating copy to clipboard operation
sentry-dotnet copied to clipboard

Unrecognized username value

Open MichaelShapiro opened this issue 8 months ago • 7 comments

Package

Sentry.Maui

.NET Flavor

.NET

.NET Version

9.0.203

OS

Any (not platform specific)

OS Version

No response

Development Environment

Visual Studio v17.x

SDK Version

5.5.0

Self-Hosted Sentry Version

No response

Workload Versions

android 35.0.39/9.0.100 VS 17.13.35931.197 ios 18.2.9180/9.0.100 VS 17.13.35931.197 maccatalyst 18.2.9180/9.0.100 VS 17.13.35931.197 maui-windows 9.0.14/9.0.100 VS 17.13.35931.197

UseSentry or SentrySdk.Init call

                sentryOptions.Dsn = "https://XXXXXXX";
                sentryOptions.Debug = false;
                sentryOptions.DiagnosticLevel = SentryLevel.Debug;

                sentryOptions.Distribution = DeviceInfo.Current.Platform.ToString();

#if DEBUG sentryOptions.Environment = "development"; sentryOptions.Release = $"LATS.Mobile@{AppInfo.Version.ToString(3)}-dev+{AppInfo.BuildString}"; #else sentryOptions.Environment = "production"; sentryOptions.Release = $"LATS.Mobile@{AppInfo.VersionString}+{AppInfo.BuildString}"; #endif

                sentryOptions.AttachScreenshot = true;
                sentryOptions.AttachStacktrace = true;
                sentryOptions.SendDefaultPii = true;


                sentryOptions.StackTraceMode = StackTraceMode.Enhanced;
                sentryOptions.IncludeTextInBreadcrumbs = false;
                sentryOptions.IncludeTitleInBreadcrumbs = false;

                // This makes the Sentry SDK to send session info. Read more here: https://docs.sentry.io/platforms/dotnet/guides/maui/configuration/releases/#sessions
                sentryOptions.AutoSessionTracking = true;

                // Send 100% of ERRORS. https://docs.sentry.io/platforms/dotnet/guides/maui/configuration/sampling/#sampling-error-events
                sentryOptions.SampleRate = 1;

                // Send 100% of TRANSACTIONS. https://docs.sentry.io/platforms/dotnet/guides/maui/configuration/sampling/#sampling-transaction-events
                sentryOptions.TracesSampleRate = 1.0;

                // This must be set only AFTER the tracing was enabled above (TracesSampleRate) https://docs.sentry.io/platforms/dotnet/guides/maui/profiling/
                sentryOptions.ProfilesSampleRate = 1.0;

                //sentryOptions.SetBeforeSend(SentryEventBeforeSend);
                //sentryOptions.SetBeforeSendTransaction(SentryTransactionBeforeSend);

Steps to Reproduce

I am sending a transaction from iOS/Android MAUI app with the following code:


ITransactionTracer transaction = SentrySdk.StartTransaction(eventName, eventName);

transaction.Contexts.Add("Event Payload", BuildContext(eventName, null, callerFunction, callerFile, payloadAsString, payloadAsDictionary)); transaction.SetTags(BuildTags(eventName, "app.event"));

transaction.Finish();


BuildContext() just adds some data to the collection, so it's irrelevant here.

The very first transaction, upon the app's launch, comes from the App.OnStart() overload. Attached are two events that were created for each platform - iOS and Droid.

Here is excerpt from each that I am puzzled about: from iOS device "user": { "id": "f752cd7b-31fa-4d44-8df4-190fa323797c", "ip_address": "zzz.zzz.zzz.zzz", "username": "mobile", "sentry_user": "id:f752cd7b-31fa-4d44-8df4-190fa323797c", "geo": { "country_code": "US", "city": "city", "subdivision": "New York", "region": "United States" }

from Droid device "user": { "id": "d5e2a329-0842-4797-ad0e-69caeb272018", "ip_address": "zzz.zzz.zzz.zzz", "username": "u0_a503", "sentry_user": "id:d5e2a329-0842-4797-ad0e-69caeb272018", "geo": { "country_code": "US", "city": "city", "subdivision": "New York", "region": "United States" }

At the time of the transactions the code that sets SentryUser has not been executed yet. However the "username" field is clearly set and is: for iOS it's always the word "mobile" for Droid is follows this format: u0_a503, u0_a502, u0_a209, u0_a501... etc. and the list goes on

Just in case, here is the code that runs AFTER the above mentioned OnStart event and after the user has been set all following events do correctly reflect the username value set by the app.

        #region Sentry
        SentrySdk.ConfigureScope(scope =>
        {
            scope.User = new SentryUser
            {
                Username = LoginUsername,
                Other = new Dictionary<string, string>()
                {
                    {"First", UserFirstName },
                    {"Last", UserLastName },
                    {"Registration", ServerRegistrationCode },
                    {"Agency", AgencyName }
                }
            };
        });
        #endregion Sentry

result of correctly set user: "user": { "id": "f752cd7b-31fa-4d44-8df4-190fa323797c", "ip_address": "xxx.xxx.xxx.xxx", "username": "mshapiroadmin", "sentry_user": "id:f752cd7b-31fa-4d44-8df4-190fa323797c", "geo": { "country_code": "US", "city": "city", "subdivision": "New York", "region": "United States" }, "data": { "other": { "Agency": "\u003C== QA ==\u003E", "First": "Mike", "Last": "Admin", "Registration": "CMATEST" } }

So, my question is: where are these values (mobile, u0_a503, u0_a502, u0_a209, u0_a501) coming from and why?

UserName_iOS.json UserName_Android.json

Expected Result

This behavior started happening perhaps a month ago or about, I do not recall exactly. But what I do remember the "user" field used to be empty if the scope's user was not set. I do not know what the intended behavior is, but it is very confusing seeing these random "user" names in he log.

Please help. Thank you,

Actual Result

"user": { "id": "f752cd7b-31fa-4d44-8df4-190fa323797c", "ip_address": "zzz.zzz.zzz.zzz", "username": "mobile", "sentry_user": "id:f752cd7b-31fa-4d44-8df4-190fa323797c", "geo": { "country_code": "US", "city": "city", "subdivision": "New York", "region": "United States" }

from Droid device "user": { "id": "d5e2a329-0842-4797-ad0e-69caeb272018", "ip_address": "zzz.zzz.zzz.zzz", "username": "u0_a503", "sentry_user": "id:d5e2a329-0842-4797-ad0e-69caeb272018", "geo": { "country_code": "US", "city": "city", "subdivision": "New York", "region": "United States" }

MichaelShapiro avatar Apr 14 '25 22:04 MichaelShapiro

@MichaelShapiro I think the default value for username either comes from the Environment: https://github.com/getsentry/sentry-dotnet/blob/ee62bb942b6bebc6b835130a5192aa68a31b6f54/src/Sentry/Internal/Enricher.cs#L88-L91

Or we get it from the Java/Cocoa SDKs: https://github.com/getsentry/sentry-dotnet/blob/438ae83fd12beee596d64be3b5876eabb81c94e0/src/Sentry/Scope.cs#L113-L120

At the time of the transactions the code that sets SentryUser has not been executed yet. However the "username" field is clearly set and is: for iOS it's always the word "mobile" for Droid is follows this format: u0_a503, u0_a502, u0_a209, u0_a501... etc. and the list goes on

You could potentially use the OnBeforeSendTransaction callback to clear the username when it matched one of those patterns:

    options.SetBeforeSendTransaction((t, h) =>
    {
        if (t.User.Username == "Foo")
        {
            t.User.Username = "Anon";
        }

        return t;
    });

jamescrosswell avatar Apr 15 '25 00:04 jamescrosswell

@jamescrosswell Thank you for advice and pointing to the source of this mysterious user name. Is this behavior intended or it can be classified as defect? or improvement? It wasn't setting the username on start to these default values before.

MichaelShapiro avatar Apr 15 '25 15:04 MichaelShapiro

@jamescrosswell a quick follow up - I really can't filter out specific user name patters unfortunately - as unusual as it is but in one of our user identity repositories there is an account with user name being... yep.. just "mobile" :) So, I'd have to get more creative about it somehow. But really hope a bit more clarification can be provided on whether to expect this default assignment to a username field to be changed or it will remain like this. Thank you!

MichaelShapiro avatar Apr 15 '25 15:04 MichaelShapiro

@MichaelShapiro you could check (log values) to see whether this is coming from Environment.UserName. If it is, then I think the SDK is doing what it's supposed to.

If it's not coming from the Environment then a bit more digging would be required to discover/understand how the Cocoa and Java SDKs infer the username...

Perhaps you could set some kind of flag when the code that sets SentryUser gets executed. In your BeforeSendTransaction handler, you check to see if that flag has been set or not and erase the UserName if it hasn't?

jamescrosswell avatar Apr 15 '25 23:04 jamescrosswell

@MichaelShapiro I think you might be able to work around this by setting IsEnvironmentUser to false in the SentryOptions when initialising the SDK.

jamescrosswell avatar May 13 '25 02:05 jamescrosswell

The mobile is the iOS device name (can't recall if set on simulators or real devices) so that's the reason why it is there. Same goes for Android.

One suggestion would be to set IsEnvironmentUser as false by default on MAUI SDK.

lucas-zimerman avatar May 13 '25 07:05 lucas-zimerman

One suggestion would be to set IsEnvironmentUser as false by default on MAUI SDK.

That sounds like a good idea but potentially a breaking change for some SDK users so maybe we do this as part of the next major release.

jamescrosswell avatar May 14 '25 08:05 jamescrosswell