自定义 gRPC 拦截器
使用集合让一切井井有条
根据您的偏好保存内容并对其进行分类。
.NET 客户端库在内部使用 gRPC 拦截器进行日志记录,但它也允许您添加自己的自定义 gRPC 拦截器。此功能可用于将指标记录到自定义日志聚合器,或转换 Google Ads API 请求。
如需添加自定义 gRPC 拦截器,请实现一个扩展 Grpc.Core.Interceptors.Interceptor
类的类,并使用 AddInterceptor
方法将其附加到 GoogleAdsClient
。
请注意,拦截流式传输和非流式传输 gRPC 请求分别需要替换 Interceptor
类的两种不同方法:AsyncUnaryCall
和 AsyncServerStreamingCall
。
Google.Ads.Gax.Interceptors
命名空间提供可在自定义拦截器中使用的实用程序类,以简化异常处理。
以下代码示例实现了流式和非流式 gRPC 调用拦截器:
// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using CommandLine;
using Google.Api.Gax;
using Google.Ads.Gax.Examples;
using Google.Ads.Gax.Interceptors;
using Google.Ads.GoogleAds.Lib;
using Google.Ads.GoogleAds.V21.Errors;
using Google.Ads.GoogleAds.V21.Services;
using Grpc.Core;
using Grpc.Core.Interceptors;
using System;
using System.Threading.Tasks;
namespace Google.Ads.GoogleAds.Examples.V21
{
/// <summary>
/// This code example shows how to add a custom gRPC interceptor.
/// </summary>
public class AddCustomGrpcInterceptor : ExampleBase
{
/// <summary>
/// Command line options for running the <see cref="AddCustomGrpcInterceptor"/> example.
/// </summary>
public class Options : OptionsBase
{
/// <summary>
/// The Google Ads customer ID for which the call is made.
/// </summary>
[Option("customerId", Required = true, HelpText =
"The Google Ads customer ID for which the call is made.")]
public long CustomerId { get; set; }
}
/// <summary>
/// Main method, to run this code example as a standalone application.
/// </summary>
/// <param name="args">The command line arguments.</param>
public static void Main(string[] args)
{
Options options = ExampleUtilities.ParseCommandLine<Options>(args);
AddCustomGrpcInterceptor codeExample = new AddCustomGrpcInterceptor();
Console.WriteLine(codeExample.Description);
GoogleAdsClient client = new GoogleAdsClient();
// Add a custom interceptor.
client.AddInterceptor(new CustomInterceptor());
codeExample.Run(client,
options.CustomerId);
}
/// <summary>
/// Returns a description about the code example.
/// </summary>
public override string Description =>
"This code example shows how to add a custom gRPC interceptor.";
/// <summary>
/// Runs the code example.
/// </summary>
/// <param name="client">The Google Ads client.</param>
/// <param name="customerId">The Google Ads customer ID for which the call is made.</param>
public void Run(GoogleAdsClient client, long customerId)
{
// Get the GoogleAdsService.
GoogleAdsServiceClient googleAdsService = client.GetService(
Services.V21.GoogleAdsService);
// Create a query that will retrieve all campaigns, just to demonstrate usage of the
// custom interceptor.
string query = @"SELECT
campaign.id,
FROM campaign
ORDER BY campaign.id";
try
{
// Issue a streaming search request; we don't need to do anything with the response
// here, we just want to demonstrate usage of the interceptor.
googleAdsService.SearchStream(customerId.ToString(), query,
delegate (SearchGoogleAdsStreamResponse resp){}
);
}
catch (GoogleAdsException e)
{
Console.WriteLine("Failure:");
Console.WriteLine($"Message: {e.Message}");
Console.WriteLine($"Failure: {e.Failure}");
Console.WriteLine($"Request ID: {e.RequestId}");
throw;
}
try
{
// Issue a non-streaming call.
PagedEnumerable<SearchGoogleAdsResponse, GoogleAdsRow> response =
googleAdsService.Search(customerId.ToString(), query);
foreach (GoogleAdsRow googleAdsRow in response)
{
// The response for Search is lazy, meaning that the actual gRPC call will be
// sent only when the response is actually accessed; to demonstrate usage of
// the interceptor, then, we need to ensure the call is sent by looping
// through the response results.
Console.WriteLine("Campaign with ID {0} was found.",
googleAdsRow.Campaign.Id, googleAdsRow.Campaign.Name);
}
}
catch (GoogleAdsException e)
{
Console.WriteLine("Failure:");
Console.WriteLine($"Message: {e.Message}");
Console.WriteLine($"Failure: {e.Failure}");
Console.WriteLine($"Request ID: {e.RequestId}");
throw;
}
}
}
/// <summary>
/// A custom interceptor for both streaming and non-streaming gRPC calls.
/// </summary>
internal class CustomInterceptor : Interceptor
{
public override AsyncUnaryCall<TResponse> AsyncUnaryCall<TRequest, TResponse>(
TRequest request, ClientInterceptorContext<TRequest, TResponse> context,
AsyncUnaryCallContinuation<TRequest, TResponse> continuationCallback)
{
AsyncUnaryCall<TResponse> call = continuationCallback(request, context);
Action<Task<TResponse>> callback = delegate (Task<TResponse> oldTask)
{
Console.WriteLine($"Intercepted a non-streaming call to {context.Method.Name}");
};
return UnaryRpcInterceptor.Intercept(call, callback);
}
public override AsyncServerStreamingCall<TResponse> AsyncServerStreamingCall<TRequest, TResponse>(
TRequest request, ClientInterceptorContext<TRequest, TResponse> context,
AsyncServerStreamingCallContinuation<TRequest, TResponse> continuation)
{
AsyncServerStreamingCall<TResponse> call = continuation(request, context);
StreamingRpcInterceptor<TResponse> responseStream = null;
responseStream = new StreamingRpcInterceptor<TResponse>(call.ResponseStream,
delegate (TResponse response, AggregateException rpcException)
{
Console.WriteLine($"Intercepted a streaming call to {context.Method.Name}");
});
return new AsyncServerStreamingCall<TResponse>(
responseStream,
call.ResponseHeadersAsync,
call.GetStatus,
call.GetTrailers,
call.Dispose
);
}
}
}
如未另行说明,那么本页面中的内容已根据知识共享署名 4.0 许可获得了许可,并且代码示例已根据 Apache 2.0 许可获得了许可。有关详情,请参阅 Google 开发者网站政策。Java 是 Oracle 和/或其关联公司的注册商标。
最后更新时间 (UTC):2025-08-26。
[null,null,["最后更新时间 (UTC):2025-08-26。"],[[["\u003cp\u003eStarting with version 19.0.0, the Google Ads API client library for .NET will no longer support .NET 5.0, requiring users to upgrade before the end of 2024 for continued functionality.\u003c/p\u003e\n"],["\u003cp\u003eThe .NET client library allows adding custom gRPC interceptors for tasks like logging metrics to custom aggregators or transforming Google Ads API requests.\u003c/p\u003e\n"],["\u003cp\u003eCustom interceptors are implemented by extending the \u003ccode\u003eGrpc.Core.Interceptors.Interceptor\u003c/code\u003e class and attached to the \u003ccode\u003eGoogleAdsClient\u003c/code\u003e using the \u003ccode\u003eAddInterceptor\u003c/code\u003e method.\u003c/p\u003e\n"],["\u003cp\u003eInterception of streaming and non-streaming calls requires overriding the \u003ccode\u003eAsyncServerStreamingCall\u003c/code\u003e and \u003ccode\u003eAsyncUnaryCall\u003c/code\u003e methods, respectively, within the custom interceptor class.\u003c/p\u003e\n"]]],[],null,["# Custom gRPC interceptors\n\nThe .NET client library internally uses gRPC [interceptors](//grpc.io/docs/guides/interceptors/) for logging purposes, but it also lets\nyou add your own custom gRPC interceptors. This feature can be used for logging\nmetrics to a custom log aggregator or to transform Google Ads API requests.\n\nTo add a custom gRPC interceptor, implement a class extending the\n`Grpc.Core.Interceptors.Interceptor` class and attach it to your\n`GoogleAdsClient` with the `AddInterceptor` method.\n\nNote that intercepting streaming and non-streaming gRPC requests require\noverriding two different methods of the `Interceptor` class:\n`AsyncUnaryCall` and `AsyncServerStreamingCall`, respectively.\n\nThe `Google.Ads.Gax.Interceptors` namespace provides utility classes that can be\nused in custom interceptors to facilitate exception handling.\n\nThe following code example implements both a streaming and a non-streaming gRPC\ncall interceptor:\n\n\n```objective-c\n// Copyright 2024 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\nusing CommandLine;\nusing Google.Api.Gax;\nusing Google.Ads.Gax.Examples;\nusing Google.Ads.Gax.Interceptors;\nusing Google.Ads.GoogleAds.Lib;\nusing Google.Ads.GoogleAds.V21.Errors;\nusing Google.Ads.GoogleAds.V21.Services;\nusing Grpc.Core;\nusing Grpc.Core.Interceptors;\nusing System;\n\nusing System.Threading.Tasks;\n\nnamespace Google.Ads.GoogleAds.Examples.V21\n{\n /// \u003csummary\u003e\n /// This code example shows how to add a custom gRPC interceptor.\n /// \u003c/summary\u003e\n public class AddCustomGrpcInterceptor : ExampleBase\n {\n /// \u003csummary\u003e\n /// Command line options for running the \u003csee cref=\"AddCustomGrpcInterceptor\"/\u003e example.\n /// \u003c/summary\u003e\n public class Options : OptionsBase\n {\n /// \u003csummary\u003e\n /// The Google Ads customer ID for which the call is made.\n /// \u003c/summary\u003e\n [Option(\"customerId\", Required = true, HelpText =\n \"The Google Ads customer ID for which the call is made.\")]\n public long CustomerId { get; set; }\n }\n\n /// \u003csummary\u003e\n /// Main method, to run this code example as a standalone application.\n /// \u003c/summary\u003e\n /// \u003cparam name=\"args\"\u003eThe command line arguments.\u003c/param\u003e\n public static void Main(string[] args)\n {\n Options options = ExampleUtilities.ParseCommandLine\u003cOptions\u003e(args);\n\n AddCustomGrpcInterceptor codeExample = new AddCustomGrpcInterceptor();\n Console.WriteLine(codeExample.Description);\n GoogleAdsClient client = new GoogleAdsClient();\n // Add a custom interceptor.\n client.AddInterceptor(new CustomInterceptor());\n codeExample.Run(client,\n options.CustomerId);\n }\n\n /// \u003csummary\u003e\n /// Returns a description about the code example.\n /// \u003c/summary\u003e\n public override string Description =\u003e\n \"This code example shows how to add a custom gRPC interceptor.\";\n\n /// \u003csummary\u003e\n /// Runs the code example.\n /// \u003c/summary\u003e\n /// \u003cparam name=\"client\"\u003eThe Google Ads client.\u003c/param\u003e\n /// \u003cparam name=\"customerId\"\u003eThe Google Ads customer ID for which the call is made.\u003c/param\u003e\n public void Run(GoogleAdsClient client, long customerId)\n {\n // Get the GoogleAdsService.\n GoogleAdsServiceClient googleAdsService = client.GetService(\n Services.V21.GoogleAdsService);\n\n // Create a query that will retrieve all campaigns, just to demonstrate usage of the\n // custom interceptor.\n string query = @\"SELECT\n campaign.id,\n FROM campaign\n ORDER BY campaign.id\";\n\n try\n {\n // Issue a streaming search request; we don't need to do anything with the response\n // here, we just want to demonstrate usage of the interceptor.\n googleAdsService.SearchStream(customerId.ToString(), query,\n delegate (SearchGoogleAdsStreamResponse resp){}\n );\n }\n catch (GoogleAdsException e)\n {\n Console.WriteLine(\"Failure:\");\n Console.WriteLine($\"Message: {e.Message}\");\n Console.WriteLine($\"Failure: {e.Failure}\");\n Console.WriteLine($\"Request ID: {e.RequestId}\");\n throw;\n }\n try\n {\n // Issue a non-streaming call.\n PagedEnumerable\u003cSearchGoogleAdsResponse, GoogleAdsRow\u003e response =\n googleAdsService.Search(customerId.ToString(), query);\n foreach (GoogleAdsRow googleAdsRow in response)\n {\n // The response for Search is lazy, meaning that the actual gRPC call will be\n // sent only when the response is actually accessed; to demonstrate usage of\n // the interceptor, then, we need to ensure the call is sent by looping\n // through the response results.\n Console.WriteLine(\"Campaign with ID {0} was found.\",\n googleAdsRow.Campaign.Id, googleAdsRow.Campaign.Name);\n }\n }\n catch (GoogleAdsException e)\n {\n Console.WriteLine(\"Failure:\");\n Console.WriteLine($\"Message: {e.Message}\");\n Console.WriteLine($\"Failure: {e.Failure}\");\n Console.WriteLine($\"Request ID: {e.RequestId}\");\n throw;\n }\n }\n }\n\n /// \u003csummary\u003e\n /// A custom interceptor for both streaming and non-streaming gRPC calls.\n /// \u003c/summary\u003e\n internal class CustomInterceptor : Interceptor\n {\n\n public override AsyncUnaryCall\u003cTResponse\u003e AsyncUnaryCall\u003cTRequest, TResponse\u003e(\n TRequest request, ClientInterceptorContext\u003cTRequest, TResponse\u003e context,\n AsyncUnaryCallContinuation\u003cTRequest, TResponse\u003e continuationCallback)\n {\n AsyncUnaryCall\u003cTResponse\u003e call = continuationCallback(request, context);\n\n Action\u003cTask\u003cTResponse\u003e\u003e callback = delegate (Task\u003cTResponse\u003e oldTask)\n {\n Console.WriteLine($\"Intercepted a non-streaming call to {context.Method.Name}\");\n };\n\n return UnaryRpcInterceptor.Intercept(call, callback);\n }\n\n public override AsyncServerStreamingCall\u003cTResponse\u003e AsyncServerStreamingCall\u003cTRequest, TResponse\u003e(\n TRequest request, ClientInterceptorContext\u003cTRequest, TResponse\u003e context,\n AsyncServerStreamingCallContinuation\u003cTRequest, TResponse\u003e continuation)\n {\n AsyncServerStreamingCall\u003cTResponse\u003e call = continuation(request, context);\n StreamingRpcInterceptor\u003cTResponse\u003e responseStream = null;\n\n responseStream = new StreamingRpcInterceptor\u003cTResponse\u003e(call.ResponseStream,\n delegate (TResponse response, AggregateException rpcException)\n {\n Console.WriteLine($\"Intercepted a streaming call to {context.Method.Name}\");\n });\n\n return new AsyncServerStreamingCall\u003cTResponse\u003e(\n responseStream,\n call.ResponseHeadersAsync,\n call.GetStatus,\n call.GetTrailers,\n call.Dispose\n );\n }\n }\n}\nhttps://github.com/googleads/google-ads-dotnet/blob/ada966e1983b655e82172b6c3e7d9b091b522377/Google.Ads.GoogleAds/examples/AdvancedOperations/AddCustomGrpcInterceptor.cs\n \n```\n\n\u003cbr /\u003e"]]