Page Summary
-
The .NET client library logs Google Ads API requests, responses, and summary messages.
-
Logs can be directed to a
TraceListeneror integrated into an existingILoggerinstance. -
Log levels vary based on the outcome of the API call (success, error, partial failure).
-
The request ID, crucial for troubleshooting, can be extracted from logs, API call responses, or exceptions.
-
Advanced gRPC-level logging is available for more detailed troubleshooting but can be voluminous.
-
Legacy .NET Framework apps can configure
TraceListenerlogging via App.config.
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 lines in
your Main method before making any API calls:
using Google.Ads.GoogleAds.Util;
// Detailed logs.
TraceUtilities.Configure(
TraceUtilities.DETAILED_REQUEST_LOGS_SOURCE,
"logs/details.log",
System.Diagnostics.SourceLevels.All);
// Summary logs.
TraceUtilities.Configure(
TraceUtilities.SUMMARY_REQUEST_LOGS_SOURCE,
"logs/summary.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 into your existing logging infrastructure.
First, create a LoggerFactory, or if you already have one, add the filters
for Google Ads API logs:
var loggerFactory = LoggerFactory.Create(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 at different log levels:
- Successful API response: Summary is logged at
INFO; full request and response are logged atDEBUG. - API error response: Summary message is logged at
WARN; full request and response are logged atINFO. - Partial failures: Logged at
DEBUG.
Request ID
In most cases, the logs generated by the client library provide sufficient details to troubleshoot your issues. When you reach out to support, either provide the logs (which redact sensitive authentication fields by default) or share the request ID, which is logged as part of the response log.
If you prefer capturing the request ID programmatically, use one of the following approaches.
Extract from ordinary unary API calls
You can use a custom CallSettings with a TrailingMetadataHandler to capture
request IDs from regular unary calls:
CallSettings callSettings = CallSettings.FromTrailingMetadataHandler(
metadata =>
{
// Extract and log the request ID from the trailing metadata.
string requestId = metadata.Get("request-id")?.Value;
Console.WriteLine($"Request ID: {requestId}");
});
// Add the campaigns.
MutateCampaignsResponse retVal = campaignService.MutateCampaigns(
customerId.ToString(), operations.ToArray(), callSettings);
Extract from 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.V25.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,
(SearchGoogleAdsStreamResponse resp) =>
{
// Extract the request ID from the response.
string requestId = resp.RequestId;
Console.WriteLine($"Request ID: {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;
Console.WriteLine($"Failed Request ID: {requestId}");
}
Configure advanced logging
If the API log doesn't give you enough details, enable lower-level logging at the gRPC transport level. Keep in mind that the output can be voluminous.
When using the default Grpc.Net.Client transport, configure transport-level
logs through .NET's ILogger provider by adding a filter for
the Grpc category (for example, builder.AddFilter("Grpc", LogLevel.Debug)).
If you are using the legacy Grpc.Core transport (UseGrpcCore = true), gRPC
logs are written to stderr by default, or you can attach your own logger as
shown in the following example. For more details, see the
supported gRPC 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 modern .NET
targets.
To use this feature, 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 a 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 a 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 Google Ads .NET libraries. The default level is set to Warning. To disable all messages, set this value to Off. --> <add name="GoogleAds.DeprecationMessages" value="Warning" /> <!-- Use this trace switch to control the detailed request logs written by Google 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 Google 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.configthen 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>