Logging

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 
 ); 
 

Note that TraceListeners.Configure should only be called once per application lifecycle, as the TraceListener it creates will automatically be reused across all API requests made by the application; you don't need to create a new one for each API request.

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 
 . 
 V21 
 . 
 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:

  1. 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> 
    
  2. 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> 
    
Design a Mobile Site
View Site in Mobile | Classic
Share by: