The .NET client library logs requests, responses, and summary messages made to
the Google Ads API. The logs can be written to a custom
TraceListener
,
or to a custom
ILogger
instance.
TraceListener
You can enable logging to a TraceListener
by adding the following line in your
Main
method before making any API calls.
using Google.Ads.GoogleAds.Util;
...
// Detailed logs.
TraceUtilities.Configure(TraceUtilities.DETAILED_REQUEST_LOGS_SOURCE,
"C:\\logs\\details.log", System.Diagnostics.SourceLevels.All);
// Summary logs.
TraceUtilities.Configure(TraceUtilities.SUMMARY_REQUEST_LOGS_SOURCE,
"C:\\logs\\details.log", System.Diagnostics.SourceLevels.All);
ILogger
If you're already using an ILogger
for your application logs, this solution
lets you integrate Google Ads API logs in your existing logs.
First, create a LoggerFactory
, or if you already have one, add the filters
for Google Ads API logs:
var loggerFactory = LoggerFactory.Create(delegate (ILoggingBuilder builder)
{
// Log to stdout.
builder.AddConsole();
builder.AddFilter(TraceUtilities.SUMMARY_REQUEST_LOGS_SOURCE, LogLevel.Trace);
builder.AddFilter(TraceUtilities.DETAILED_REQUEST_LOGS_SOURCE, LogLevel.Trace);
});
Then, use the LoggerFactory
to create loggers for request and response
summaries and details:
ILogger summaryLogger = loggerFactory.CreateLogger(TraceUtilities.SUMMARY_REQUEST_LOGS_SOURCE);
ILogger detailLogger = loggerFactory.CreateLogger(TraceUtilities.DETAILED_REQUEST_LOGS_SOURCE);
Finally, configure the client library to redirect its traces to your ILogger
instances:
TraceUtilities.ConfigureSummaryLogger(summaryLogger);
TraceUtilities.ConfigureDetailLogger(detailLogger);
This solution lets you integrate Google Ads API request and response logs into existing logging frameworks, such as Log4Net, NLog, and Serilog.
Log levels
The library logs different types of events to different log levels. For a
successful API response, the summary is logged at INFO
, and the full
request and responses are logged at DEBUG
.
On a request that results in an API error, the summary message is logged at
WARN
, and the full request and response are logged at INFO
.
Partial failures are logged at DEBUG
.
Request ID
In most cases, the logs generated by the client library provide sufficient details to troubleshoot your issues. When reaching out to the support forum/aliases, you can either provide the logs (which redacts sensitive information by default) or just share the request ID (which is logged as part of the response log).
If you prefer capturing the request ID yourself, you could use one of the following approaches:
Extraction through ordinary API calls
You can use a custom CallSetting
with a TrailingMetadataHandler
to capture
request IDs from regular unary calls.
CallSettings callSettings = CallSettings.FromTrailingMetadataHandler(
delegate (Metadata metadata) {
// Extract the request ID from the trailing metadata.
string requestId = metadata.Get("request-id").Value;
});
// Add the campaigns.
MutateCampaignsResponse retVal = campaignService.MutateCampaigns(
customerId.ToString(), operations.ToArray(), callSettings);
Extraction through streaming API calls
The request ID is returned as part of the response object for streaming API
calls. For example, you can get the request ID for a SearchStream
call as
follows:
// Get the GoogleAdsService.
GoogleAdsServiceClient googleAdsService = client.GetService(
Services.V18.GoogleAdsService);
// Retrieve all campaigns.
string query = @"SELECT
campaign.id,
campaign.name,
campaign.network_settings.target_content_network
FROM campaign
ORDER BY campaign.id";
// Issue a search request.
googleAdsService.SearchStream(customerId.ToString(), query,
delegate (SearchGoogleAdsStreamResponse resp)
{
// Extract the request ID from the response.
string requestId = resp.RequestId;
foreach (GoogleAdsRow googleAdsRow in resp.Results)
{
Console.WriteLine("Campaign with ID {0} and name '{1}' was found.",
googleAdsRow.Campaign.Id, googleAdsRow.Campaign.Name);
}
}
);
Exceptions
The request ID is returned as part of the GoogleAdsException
exception
whenever an API call fails.
try
{
// Make an API call.
...
}
catch (GoogleAdsException e)
{
string requestId = e.RequestId;
}
Advanced logging
If the API log doesn't give you enough details, enable more low level logging at the gRPC level. Keep in mind that the output can be voluminous. The gRPC logs are written to stderr, but you can attach your own logger as shown below. Supported environment variables.
Environment.SetEnvironmentVariable("GRPC_VERBOSITY", "DEBUG");
Environment.SetEnvironmentVariable("GRPC_TRACE", "http");
GrpcEnvironment.SetLogger(new ConsoleLogger());
TraceListener configuration using App.config (legacy)
If your app builds for a .NET Framework target, you can load the logging
configuration from your app's App.config
or Web.config
file. This is a
legacy .NET functionality that is not supported for apps built for .NET Core
targets.
To use this feature, you need to add the following changes to your configuration file:
Add the following snippet under the
<configuration>
section.<system.diagnostics> <sources> <source name="GoogleAds.DeprecationMessages" switchName="GoogleAds.DeprecationMessages" switchType="System.Diagnostics.SourceSwitch"> <listeners> <add name="myListener" type="System.Diagnostics.EventLogTraceListener" initializeData="Application"/> </listeners> </source> <source name="GoogleAds.DetailedRequestLogs" switchName="GoogleAds.DetailedRequestLogs" switchType="System.Diagnostics.SourceSwitch"> <listeners> <add name="detailedRequestLogListener" type="System.Diagnostics.ConsoleTraceListener" initializeData="true"/> <!-- Use the following to log to file. Modify the initializeData attribute to control the path to the detailed request log file. --> <!-- <add name="detailedRequestLogListener" type="System.Diagnostics.TextWriterTraceListener" initializeData="C:\Logs\detailed_logs.log"/> <remove name="Default"/> --> </listeners> </source> <source name="GoogleAds.SummaryRequestLogs" switchName="GoogleAds.SummaryRequestLogs" switchType="System.Diagnostics.SourceSwitch"> <listeners> <add name="summaryRequestLogListener" type="System.Diagnostics.ConsoleTraceListener" initializeData="true"/> <!-- Use the following to log to file. Modify the initializeData attribute to control the path to the summary request log file. --> <!-- <add name="summaryRequestLogListener" type="System.Diagnostics.TextWriterTraceListener" initializeData="C:\Logs\summary_logs.log"/> --> <remove name="Default"/> </listeners> </source> </sources> <switches> <!-- Use this trace switch to control the deprecation trace messages written by Ads* .NET libraries. The default is level is set to Warning. To disable all messages, set this value to Off. See msdn.microsoft.com/en-us/library/system.diagnostics.sourcelevels.aspx for all possible values this key can take. --> <add name="GoogleAds.DeprecationMessages" value="Warning"/> <!-- Use this trace switch to control the detailed request logs written by Ads* .NET libraries. The default level is set to Off. Logs are generated at both the Error and Information levels. --> <add name="GoogleAds.DetailedRequestLogs" value="Off"/> <!-- Use this trace switch to control the summary request logs written by Ads* .NET libraries. The default level is set to Off. Logs are generated at both the Error and Information levels. --> <add name="GoogleAds.SummaryRequestLogs" value="Off"/> </switches> <trace autoflush="true"/> </system.diagnostics>
Add the following snippet under the
<configSections>
section.<section name="system.diagnostics" type="System.Diagnostics.SystemDiagnosticsSection"/>
Your
App.config
then looks like this:<?xml version="1.0" encoding="utf-8"?> <configuration> <configSections> <section name="GoogleAdsApi" type="System.Configuration.DictionarySectionHandler"/> <section name="system.diagnostics" type="System.Diagnostics.SystemDiagnosticsSection"/> </configSections> <GoogleAdsApi> <!-- Google Ads API settings. --> </GoogleAdsApi> <system.diagnostics> <!-- Logging settings. --> </system.diagnostics> </configuration>