question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Google.Cloud.Diagnostics does not seem to be working with BackgroundService

See original GitHub issue

Environment details

  • OS: Windows 10
  • .NET version: .net core 3.1
  • Package name and version: Google.Cloud.Diagnostics.AspNetCore v4.0.0

Problem Description

Been trying to get tracing information over to GCP by following this documentation (http://googleapis.github.io/google-cloud-dotnet/docs/Google.Cloud.Diagnostics.AspNetCore/)

I’ve noticed that none of the tracing information (nor metrics and error logs) flow through to GCP when execution occurs in a background service (as implemented following this example https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services?view=aspnetcore-3.1&tabs=visual-studio#queued-background-tasks). I did however, notice that everything shows up if I don’t use background service (aka just hitting the method directly from the controller instead of queuing it up).

Is this a known issue? Is there something I need to pass along to the background service in order to get information flowing? This is a snippet of how I establish tracing (I’m just trying to obtain tracing anytime we perform http requests on our httpclient)

public class TraceHandler : DelegatingHandler
    {
        private IManagedTracer _tracer;

        public TraceHandler(IManagedTracer tracer)
        {
            _tracer = tracer;
        }

        protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            using (_tracer.StartSpan($"{request.RequestUri}"))
            {
                var response = await base.SendAsync(request, cancellationToken);
                return response;
            }
        }
    }

This is what is currently happening in my endpoint (which doesn’t work):

[HttpGet("[controller]/[action]")]
        public IActionResult AddToQueue()
        {
            if (!_cancellationToken.IsCancellationRequested)
            {
                Task.Run(() => QueueWork());
            }

            return Accepted();
        }

QueueWork does the following:

private void QueueWork()
        {
            _taskQueue.QueueBackgroundWorkItem(async token => await _example.PerformWork());
        }

_taskQueue.QueueBackgroundWorkItem is basically a copy of the implementation in the article described above.

Now if the controller were to call _example.PerformWork directly, then I do see trace logs on GCP.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:7 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
amanda-tarafacommented, Apr 17, 2020

@mahesh-bennie What you are seeing is not an issue with the Diagnostics library, it’s just working as intended. All the setup described here is for tracing to happen automatically within a request. And that is working as expected when you call PerformWork directly from your controller instead of queueing it. For that to happen we rely on the ASP.NET Core pipeline to execute, in particular our own custom middleware. The BackgroundService executes outside of requests (that is actually its sole purpose), and not as part of the ASP.NET Core pipeline, so our custom middleware is not involved and trace is not fully setup for the BackgroundService. The good news is that you only need a couple lines of code to set it up yourself on your BackgroundService (luckily ASP.NET Core Dependecy Injection does work for BackgroundService and you can reuse some of the setup).

Attached you’ll find a working example. My controller has two actions, GetInmediate (calls DoWork) and GetDeffered (enqueus DoWork). I skipped the DelegatingHandler bit for the example, I’m simply starting the trace on the actions, one or the other approach won’t make a difference. And DoWork does receive a tracer, to make sure that it uses the correct one whether is called from within a request or from within the BackgroundService. The BackgroundService implementation is copied from the MS tutorial you linked, I removed the logger bit to make the code simpler (this is just for demonstration anyways) and I added the two lines of code that you’ll be interested in, in QueuedHostedService. You’ll have to change the PROJECT-ID placeholder on Startup.cs to get this working.

Note that for GetInmediate you’ll get one trace containing 2 spans, one for the request and one for DoWork. For GetDeffered you’ll get two traces with one span each, one trace for the request and one trace for DoWork. This is as expected and there is no way around it by definition. When DoWork is executed by the background service, the GetDeffered request ended “a long time ago” and the request trace with it.

Let me know if this answers your question. BackgroundServiceLogging3.1.zip

1reaction
amanda-tarafacommented, Apr 14, 2020

I’m looking into this. Will get back when I know more.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Google.Cloud.Diagnostics.Common
Diagnostics.Common is a .NET Core instrumentation library for Google Logging, Error Reporting and Tracing. It allows for simple integration ...
Read more >
Google.Cloud.Diagnostics.AspNetCore3 debug level not ...
Short Answer: Google.Cloud.Diagnostics.AspNetCore3 does not use appsettings.json (at least for now) and one must explicitly set log levels.
Read more >
.net core monitoring : r/csharp
Hi guys, I was wondering, apart from Health checks and Logging events into a database. What other diagnostics could i use to…
Read more >
Running a .NET Core Generic Host App as a Windows Service
In this post we'll explore how to take a .NET Core console application, running on the Generic Host, utilising IHostedService and deploy it ......
Read more >
Service | Android Developers
The Service object itself does not imply it is running in its own process; ... However, since the user is not directly aware...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found