-
Notifications
You must be signed in to change notification settings - Fork 64
add SqlClientListener for diagnostic logging #914
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
Changes from 7 commits
3049f46
c52556c
32cfad5
7003cf5
c03c20a
c943bd1
3bf96a0
3e814e0
26de9f2
f0c997e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,4 +20,42 @@ Needs Logs: | |
|
||
3. Get the log file and attach it to this issue. By default this will be in `%TMP%/LogFiles/Application/Functions/Host`. | ||
|
||
**NOTE** Debug logging will include information such as Database and table names, if you do not wish to include this information you can either redact it from the logs before attaching or let us know and we will provide a way to send logs directly to us. | ||
|
||
#actions for Needs Connection Logs | ||
Needs Connection Logs: | ||
comment: | | ||
We need more info to debug your particular issue. If you could attach your SQL Client logs to the issue, it would help us fix the issue much faster. | ||
|
||
1. Set the AzureFunctions_SqlBindings_VerboseLogging to `true` in your `*.settings.json` file. | ||
|
||
```json | ||
{ | ||
"IsEncrypted": false, | ||
"Values": { | ||
"AzureWebJobsStorage": "UseDevelopmentStorage=true", | ||
"FUNCTIONS_WORKER_RUNTIME": "<dotnet>", | ||
"SqlConnectionString": "<Your Connection string>", | ||
"AzureFunctions_SqlBindings_VerboseLogging": "true", | ||
} | ||
} | ||
``` | ||
|
||
2. Set the default logging level to `Debug` and enable logging to a file. To do this ensure the following entries are in your `host.json`. ([instructions](https://learn.microsoft.com/azure/azure-functions/configure-monitoring?tabs=v2#configure-log-levels)) | ||
MaddyDev marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
```json | ||
{ | ||
"logging": { | ||
"fileLoggingMode": "always", | ||
"logLevel": { | ||
"default": "Debug" | ||
} | ||
} | ||
} | ||
``` | ||
|
||
3. Restart your function and reproduce your issue | ||
|
||
4. Get the log file and attach it to this issue. By default this will be in `%TMP%/LogFiles/Application/Functions/Host`. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually, looking at this it would be good to include instructions (for both this and the other logging message) for doing this in a deployed function too since they won't be the same. Not sure offhand what the easiest way to export the logs would be, so that might take some investigation. In the meantime I think we can actually revert the change I had you add earlier about the Function App settings and instead specify that these instructions are for local development only. Then when we figure out a way for deployed functions we can come back and update both with those instructions. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for adding the note! Might be worth making an actual issue to track updating this with instructions for deployed functions as well. (although if we do that it might actually be best to just update the instructions in our docs and then link to those from here so we don't have to remember to keep both in sync) |
||
|
||
**NOTE** Debug logging will include information such as Database and table names, if you do not wish to include this information you can either redact it from the logs before attaching or let us know and we will provide a way to send logs directly to us. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. See License.txt in the project root for license information. | ||
|
||
using System.Linq; | ||
using System.Diagnostics.Tracing; | ||
using System; | ||
using Microsoft.Extensions.Logging; | ||
|
||
namespace Microsoft.Azure.WebJobs.Extensions.Sql | ||
{ | ||
|
||
/// <summary> | ||
/// This listener class will listen for events from the SqlClientEventSource class | ||
/// and forward them to the logger. | ||
/// </summary> | ||
public class SqlClientListener : EventListener | ||
{ | ||
private readonly ILogger _logger; | ||
|
||
public SqlClientListener(ILogger logger) | ||
{ | ||
this._logger = logger; | ||
} | ||
|
||
protected override void OnEventSourceCreated(EventSource eventSource) | ||
{ | ||
// Only enable events from SqlClientEventSource. | ||
if (string.CompareOrdinal(eventSource.Name, "Microsoft.Data.SqlClient.EventSource") == 0) | ||
{ | ||
// Use EventKeyWord 2 to capture basic application flow events. | ||
// See https://docs.microsoft.com/sql/connect/ado-net/enable-eventsource-tracing for all available keywords. | ||
this.EnableEvents(eventSource, EventLevel.Informational, (EventKeywords)2); | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// This callback runs whenever an event is written by SqlClientEventSource. | ||
/// Event data is accessed through the EventWrittenEventArgs parameter. | ||
/// </summary> | ||
/// <param name="eventData">The data for the event</param> | ||
protected override void OnEventWritten(EventWrittenEventArgs eventData) | ||
{ | ||
try | ||
{ | ||
if (eventData.Payload == null) | ||
{ | ||
return; | ||
} | ||
object[] values = new object[eventData.Payload.Count]; | ||
MaddyDev marked this conversation as resolved.
Show resolved
Hide resolved
|
||
string[] keys = new string[eventData.PayloadNames.Count]; | ||
|
||
eventData.PayloadNames.CopyTo(keys, 0); | ||
eventData.Payload.CopyTo(values, 0); | ||
var payloadDictionary = keys.Select((k, i) => new { k, v = values[i].ToString() }) | ||
.ToDictionary(x => x.k, x => x.v); | ||
foreach (object payload in eventData.Payload) | ||
{ | ||
if (payload != null) | ||
{ | ||
this._logger.LogTrace($"Sending event {eventData.EventName}. Properties: {Utils.JsonSerializeObject(payloadDictionary)}"); | ||
} | ||
} | ||
} | ||
catch (Exception ex) | ||
{ | ||
this._logger.LogError($"Error sending event {eventData.EventName}. Message={ex.Message}"); | ||
MaddyDev marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
} | ||
} | ||
} | ||
} |
Uh oh!
There was an error while loading. Please reload this page.