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

Transaction cannot be started from native layer before .Net SDK initialized for Android and iOS #1609

Open
pavlo-supenko opened this issue Apr 8, 2024 · 4 comments
Labels
Bug Something isn't working Product: Performance

Comments

@pavlo-supenko
Copy link

pavlo-supenko commented Apr 8, 2024

Environment

We are using:

  • Sentry cloud solution (sentry.io)
  • Sentry Unity SDK v1.8.0/v2.0.2 (reproduced on both) installed via (OpenUPM and io.sentry.unity scope) [https://openupm.com/packages/io.sentry.unity/].
  • Unity 2021.3.15

The issue is presenting on iOS and Android devices and cant be checked in Editor because it's connected with native tracking before the engine start.

Steps to Reproduce

Android

  1. Create empty Android project.
  2. Import Sentry package.
  3. (optional I think) Enable Il2cpp backend.
  4. Enable using of custom android manifest to use custom activity.
  5. Create activity class and start transaction in OnCreate method override.
package com.unity3d.player;

import android.os.Bundle;
import android.util.Log;

import io.sentry.ISpan;
import io.sentry.ITransaction;
import io.sentry.Sentry;
import io.sentry.SpanStatus;

public class SentryCustomActivity extends UnityPlayerActivity
{

    @Override protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        
        Log.d("SentryCustomActivity", "Custom activity started");
        ITransaction activityTransaction = Sentry.startTransaction("Unity start", "activity creation");
        Log.d("SentryCustomActivity", "Transaction created");
        ISpan argumentsSpan = activityTransaction.startChild("cmd args processing");
        Log.d("SentryCustomActivity", "Span started");

        Log.d("SentryCustomActivity", "Super method invoked");

        argumentsSpan.finish(SpanStatus.OK);
        Log.d("SentryCustomActivity", "Span finished");
        activityTransaction.finish(SpanStatus.OK);
        Log.d("SentryCustomActivity", "Custom activity finished");
    }
}
  1. Create built-time and run-time Sentry configurators and enable tracing in them.
public class SentryRuntimeConfiguration : Sentry.Unity.SentryRuntimeOptionsConfiguration
{
    public override void Configure(SentryUnityOptions options)
    {
        options.EnableTracing = true;
        options.TracesSampleRate = 1f;
    }
}

public class SentryBuildTimeConfiguration : Sentry.Unity.SentryBuildTimeOptionsConfiguration
{
    public override void Configure(SentryUnityOptions options, SentryCliOptions cliOptions)
    {
        options.EnableTracing = true;
        options.TracesSampleRate = 1f;
    }
}
  1. Enable debug mode not only for editor.
  2. Build and run. Check logcat.

iOS

  1. The same steps as in Android project to create it, import Sentry, and modify build- and run-time configurators.
  2. Build project.
  3. Modify main.m file and start transaction after SentrySDK is initialized by adding lines 7, 20, 23-26.
#include <Sentry/Sentry.h>
#include "SentryOptions.m"
#include <UnityFramework/UnityFramework.h>

UnityFramework* UnityFrameworkLoad()
{
    id<SentrySpan> transaction = [SentrySDK startTransactionWithName:@"Unity start" operation:@"main"];
    
    NSString* bundlePath = nil;
    bundlePath = [[NSBundle mainBundle] bundlePath];
    bundlePath = [bundlePath stringByAppendingString: @"/Frameworks/UnityFramework.framework"];

    NSBundle* bundle = [NSBundle bundleWithPath: bundlePath];
    if ([bundle isLoaded] == false) [bundle load];

    UnityFramework* ufw = [bundle.principalClass getInstance];
    if (![ufw appController])
    {
        // unity is not initialized
        [transaction finishWithStatus:kSentrySpanStatusInternalError];
        [ufw setExecuteHeader: &_mh_execute_header];
    }
    else
    {
        [transaction finishWithStatus:kSentrySpanStatusOk];
    }
    
    return ufw;
}

int main(int argc, char* argv[])
{
    @autoreleasepool
    {
        SentryOptions* options = getSentryOptions();
        if(options != nil)
        {
            [SentrySDK startWithOptions:options];
        }

        id ufw = UnityFrameworkLoad();
        [ufw runUIApplicationMainWithArgc: argc argv: argv];
        return 0;
    }
}

Expected Result

Expect that any transactions started from native layer before .Net SDK initialized will work and all transactions appear on Sentry console.

Actual Result

Android

Transaction start operation said that Tracing is disabled but it is in build- and run-time configurators.

2024-04-08 12:23:16.020 20985-20985 SentryCustomActivity    com.teachdraw.tk.sandbox             D  Custom activity started
2024-04-08 12:23:16.021 20985-20985 Sentry                  com.teachdraw.tk.sandbox             I  Tracing is disabled and this 'startTransaction' returns a no-op.
2024-04-08 12:23:16.021 20985-20985 SentryCustomActivity    com.teachdraw.tk.sandbox             D  Transaction created
2024-04-08 12:23:16.021 20985-20985 SentryCustomActivity    com.teachdraw.tk.sandbox             D  Span started
2024-04-08 12:23:16.021 20985-20985 SentryCustomActivity    com.teachdraw.tk.sandbox             D  Super method invoked
2024-04-08 12:23:16.022 20985-20985 SentryCustomActivity    com.teachdraw.tk.sandbox             D  Span finished
2024-04-08 12:23:16.022 20985-20985 SentryCustomActivity    com.teachdraw.tk.sandbox             D  Custom activity finished

iOS

On iOS case transaction started as I see but it's not finishing because of internal_error

default	13:48:57.262723+0300	Template	[Sentry] [debug] [SentryTransactionContext:147] Created transaction context with name Unity start
default	13:48:57.262789+0300	Template	[Sentry] [debug] [SentrySpanContext:93] Created span context with trace ID 2af73caa97e647f6ba390b8b3a0add91; span ID 9b797e29c3ba4190; parent span ID (null); operation main
default	13:48:57.262845+0300	Template	[Sentry] [debug] [SentryFramesTracker:79] Initialized frame tracker <SentryFramesTracker: 0x280db2450>
default	13:48:57.264883+0300	Template	[Sentry] [debug] [SentryTracer:203] Started tracer with id: 2af73caa97e647f6ba390b8b3a0add91
default	13:48:57.265038+0300	Template	[Sentry] [debug] [SentryLaunchProfiling:157] No launch tracer present to stop.
default	13:48:57.265075+0300	Template	[Sentry] [debug] [SentryLaunchProfiling:45] Won't profile next launch due to specified options configuration: options.enableAppLaunchProfiling: 0; options.enableTracing: 0
default	13:48:57.265130+0300	Template	[Sentry] [debug] [SentryFileManager:51] No file to delete at /var/mobile/Containers/Data/Application/EF35AB1F-318A-4BF7-AFFE-90B9951F0B0B/Library/Application Support/io.sentry/profileLaunch
default	13:48:57.498689+0300	Template	[Sentry] [debug] [SentryReachability:138] SentryConnectivityCallback called with target: <SCNetworkReachability 0x102c07240 [0x1f5f00190]> {name = sentry.io (complete, 35.186.247.156), flags = 0x00000003, if_index = 9}; flags: 3
default	13:48:57.498735+0300	Template	[Sentry] [debug] [SentryReachability:103] Entered synchronized region of SentryConnectivityCallback with flags: 3
default	13:48:57.498760+0300	Template	[Sentry] [debug] [SentryReachability:119] Notifying observers...
default	13:48:57.498886+0300	Template	[Sentry] [debug] [SentryReachability:121] Notifying <SentryBreadcrumbTracker: 0x2824a8920>
default	13:48:57.498907+0300	Template	[Sentry] [debug] [SentryScope:122] Add breadcrumb: <SentryBreadcrumb: 0x2833a2ac0, {
    category = "device.connectivity";
    data =     {
        connectivity = wifi;
    };
    level = info;
    timestamp = "2024-04-08T10:48:57.492Z";
    type = connectivity;
}>
default	13:48:57.498928+0300	Template	[Sentry] [debug] [SentryReachability:121] Notifying <SentryHttpTransport: 0x2802a4660>
default	13:48:57.498948+0300	Template	[Sentry] [debug] [SentryHttpTransport:106] Internet connection is back.
default	13:48:57.498967+0300	Template	[Sentry] [debug] [SentryHttpTransport:268] sendAllCachedEnvelopes start.
default	13:48:57.499013+0300	Template	[Sentry] [debug] [SentryHttpTransport:280] No envelopes left to send.
default	13:48:57.499037+0300	Template	[Sentry] [debug] [SentryHttpTransport:362] Finished sending.
default	13:48:57.499062+0300	Template	[Sentry] [debug] [SentryReachability:125] Finished notifying observers.
default	13:48:57.764524+0300	Template	[Sentry] [debug] [SentryTracer:452] Finished trace with traceID: (null) and status: internal_error

Logs or screenshots

Android

Full log from app start

sentry-android-activity-transaction-all.log

The same log but filtered with Sentry

sentry-android-activity-transaction-filtered.log

iOS

sentry-ios-main-transaction-all.log

Project I used for test

unity-sentry-test.zip

@bitsandfoxes
Copy link
Contributor

bitsandfoxes commented Apr 8, 2024

Thanks for the detailed issue!
One thing to be aware of and to manage expectations: Currently, there is no mechanism to sync transactions and spans between the native and the managed layer. So you'd be "stuck" with native transaction - for now (tm)

@pavlo-supenko
Copy link
Author

pavlo-supenko commented Apr 8, 2024

Currently, there is no mechanism to sync transactions and spans between the native and the managed layer. So you'd be "stuck" with native transaction - for now (tm)

But it should work if I start and finish some transactions only on native layer and some another only on managed ? Am I understand correctly (that means that problem I described is valid) ?

@bitsandfoxes
Copy link
Contributor

bitsandfoxes commented Apr 8, 2024

You can start and finish things on the same layer. But there is no passing of ID happening. So the spans and transactions will be disconnected from each other based on their layer.

@pavlo-supenko
Copy link
Author

Yes, that would be great, in my case I need to track some native work we do before Unity starts separately from something inside engine, without blending Sentry layers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Something isn't working Product: Performance
Projects
Status: No status
Status: No status
Development

No branches or pull requests

2 participants