Extendアプリのカスタムメトリクス
注釈:本資料はAI技術を用いて翻訳されています。
概要
Extendアプリのカスタムメトリクスは、Extendアプリが公開するデフォルトメトリクス以外の追加メトリクスです。
この記事では、Extend Service Extensionアプリテンプレートを例として、Extendアプリにカスタムメトリクスを追加するプロセスをガイドします。ただし、ここで説明する手順はすべてのタイプのExtendアプリに適用されます。
前提条件
このウォークスルーに従う前に、Extend Service Extensionアプリのセットアップ方法を理解しておく必要があります。
アプリテンプレートのクローン
- C#
- Go
- Java
- Python
git clone https://github.com/AccelByte/extend-service-extension-csharp
git clone https://github.com/AccelByte/extend-service-extension-go
git clone https://github.com/AccelByte/extend-service-extension-java
git clone https://github.com/AccelByte/extend-service-extension-python
カスタムメトリクスの追加
この例では、GetGuildProgress関数が呼び出された回数を追跡するカウンターメトリクスを追加します。
- C#
- Go
- Java
- Python
-
メトリクスプロバイダークラスを作成して新しいメトリクスを定義します。
Classesディレクトリまたは他のディレクトリに保存します。using System;
using Prometheus;
namespace AccelByte.Extend.ServiceExtension.Server
{
public class GetGuildCountMetric
{
private Counter _Counter;
public GetGuildCountMetric()
{
_Counter = Metrics.CreateCounter(
"ab_count_get_guild_progress",
"Count number of GetGuildProgress called", labelNames: new[] { "method" });
}
public void Increment(string method)
{
_Counter.WithLabels(method).Inc();
}
}
} -
Program.csファイル内のサービスプロバイダーに新しいメトリクスを登録します。grpcサービスを登録する前に以下のコードを配置します。...
builder.Services
.AddSingleton(new GetGuildCountMetric());
... -
Services/MyService.csのgrpcサービスコンストラクタに新しいメトリクスを追加します。...
public class MyService : Service.ServiceBase
{
...
private readonly GetGuildCountMetric _GetGuildCountMetric;
...
public MyService(
ILogger<MyService> logger,
IAccelByteServiceProvider abProvider,
Tracer tracer,
GetGuildCountMetric getGuildCountMetric)
{
...
_GetGuildCountMetric = getGuildCountMetric;
}
...
} -
GetGuildProgress関数内で、関数が呼び出されるたびにメトリクスカウンターをインクリメントします。_GetGuildCountMetric.Increment("GET", context.Method);
-
Prometheus
CounterVecを作成し、main.goのcounterGetGuildProgress変数に格納して新しいメトリクスを定義します。メトリクスには1つのラベルmethodが含まれます。var (
serviceName = common.GetEnv("OTEL_SERVICE_NAME", "ExtendCustomServiceGoDocker")
logLevelStr = common.GetEnv("LOG_LEVEL", logrus.InfoLevel.String())
// 新しい変数
counterGetGuildProgress = prometheus.NewCounterVec(
prometheus.CounterOpts{
Name: "ab_count_get_guild_progress",
Help: "Count number of GetGuildProgress called",
},
[]string{"method"},
)
) -
main.goでPrometheusレジストリに
counterGetGuildProgress変数を登録します。// Prometheusメトリクスを登録
prometheusRegistry := prometheus.NewRegistry()
prometheusRegistry.MustRegister(
prometheusCollectors.NewGoCollector(),
prometheusCollectors.NewProcessCollector(prometheusCollectors.ProcessCollectorOpts{}),
prometheusGrpc.DefaultServerMetrics,
// 新しいカスタムメトリクス
counterGetGuildProgress,
) -
counterGetGuildProgress変数をGetGuildProgress関数に渡します。pkg/service/myService.goのMyServiceServerImpl構造体に新しいフィールドを追加してカスタムメトリクスを保持します。さらに、MyServiceServerImplの新しいインスタンスを作成する際にcounterGetGuildProgressを初期化するようにコンストラクタを更新します。type MyServiceServerImpl struct {
pb.UnimplementedServiceServer
tokenRepo repository.TokenRepository
configRepo repository.ConfigRepository
refreshRepo repository.RefreshTokenRepository
storage storage.Storage
counterGetGuildProgress prometheus.CounterVec // 新しいフィールド
}
func NewMyServiceServer(
tokenRepo repository.TokenRepository,
configRepo repository.ConfigRepository,
refreshRepo repository.RefreshTokenRepository,
storage storage.Storage,
counterGetGuildProgress prometheus.CounterVec, // 新しく追加
) *MyServiceServerImpl {
return &MyServiceServerImpl{
tokenRepo: tokenRepo,
configRepo: configRepo,
refreshRepo: refreshRepo,
storage: storage,
counterGetGuildProgress: counterGetGuildProgress, // 新しく追加
}
} -
GetGuildProgress関数内で、関数が呼び出されるたびにメトリクスカウンターをインクリメントします。func (g MyServiceServerImpl) GetGuildProgress(
ctx context.Context, req *pb.GetGuildProgressRequest,
) (*pb.GetGuildProgressResponse, error) {
namespace := req.Namespace
guildProgressKey := fmt.Sprintf("guildProgress_%s", req.GuildId)
// カスタムメトリクスを呼び出す
g.counterGetGuildProgress.WithLabelValues("GET").Inc()
guildProgress, err := g.storage.GetGuildProgress(namespace, guildProgressKey)
if err != nil {
return nil, status.Errorf(codes.Internal, "Error getting guild progress: %v", err)
}
return &pb.GetGuildProgressResponse{
GuildProgress: guildProgress,
}, nil
}
-
build.gradleファイルにspring-aspects依存関係を追加します。dependencies {
...
implementation 'org.springframework:spring-aspects:6.1.4'
...
testImplementation 'org.springframework:spring-aspects:6.1.4'
} -
src/main/java/net/accelbyte/extend/serviceextension/config/AppConfig.javaファイルにCountedAspectを追加します。...
import io.micrometer.core.aop.CountedAspect;
import io.micrometer.core.instrument.MeterRegistry;
@Configuration
public class AppConfig {
...
@Bean
public CountedAspect provideCounterAspect(MeterRegistry registry) {
return new CountedAspect(registry);
}
} -
src/main/java/net/accelbyte/extend/serviceextension/service/MyService.javaファイルのgetGuildProgressメソッドに@Countedアノテーションを追加します。...
import io.micrometer.core.annotation.Counted;
@GRpcService
@Slf4j
public class MyService extends ServiceGrpc.ServiceImplBase {
@Counted(value = "ab_count_get_guild_progress",
description = "Count number of GetGuildProgress called",
extraTags = { "method", "GET" })
@Override
public void getGuildProgress(
GetGuildProgressRequest request, StreamObserver<GetGuildProgressResponse> responseObserver
) {
...
}
}
-
Prometheus
Counterを作成し、サービスの.pyファイルのcounter_get_guild_progress変数に格納して新しいメトリクスを定義します。メトリクスには1つのラベルmethodが含まれます。from prometheus_client import Counter
class AsyncMyService(MyServiceServices):
def __init__(self, *args, **kwargs) -> None:
self.counter_get_guild_progress = Counter(
name="ab_count_get_guild_progress",
documentation="Count number of GetGuildProgress called",
labelnames=["method"],
unit="count",
) -
GetGuildProgress関数内で、関数が呼び出されるたびにメトリクスカウンターをインクリメントします。async def GetGuildProgress(
self, request: GetGuildProgressRequest, context: Any
) -> GetGuildProgressResponse:
# ...
self.counter_get_guild_progress.labels(method="GET").inc(amount=1)
# ...
Grafana Cloudでメトリクスを確認する
-
Admin PortalのExtendアプリ詳細ページにある
Open Grafana CloudボタンをクリックしてGrafana Cloudにアクセスします。 -
Grafana Cloudの
Exploreメニューをクリックします。
-
メトリクスデータを読み込むデータソースを選択します。
Admin Portalのアカウント権限に応じて、2つのPrometheusデータソースから選択できます。すべてのネームスペースにアクセスできる場合(スーパー管理者)、
metricsデータソース(クロスネームスペースデータ)を選択できます。特定のネームスペースのみにアクセスできる場合は、prom-<namespace>.*データソース(ネームスペースごとのデータ)のみを選択できます。
クロスネームスペースデータ 
ネームスペースごとのデータ -
必要に応じて複数のクエリを追加または削除します。ソースが選択されたら、Add queryボタンをクリックします。さらに、Query historyボタンをクリックしてクエリ履歴を表示できます。

-
カスタムメトリクスを選択するには、
Select metricドロップダウンを使用してカスタムメトリクスを検索します。また、Operationsボタンをクリックして特定の操作を適用することもできます。
複雑なクエリがある場合は、
Codeタブをクリックして高度な計算にPrometheusクエリを使用します。
以下の画像の手順に従ってください。まず、ソースを選択します(1)。次に、クエリの時間枠を選択します(2)。次に、
MetricドロップダウンボックスとLabelフィルターから値を選択します(3)。オプションで、メトリクスに特定の操作を適用します(4)。最後に、Run queryボタンをクリックしてメトリクスを表示します。
重要な注意事項
-
シリーズは、メトリクス名とラベルのキーと値のペアのセットの一意の組み合わせとして定義されます。各固有のメトリクス名とそれに対応するラベルのキーと値のペアは、個別のシリーズとして扱われます。 例:
ab_count_get_guild_progress{method="GET"} 1 -> series_count=1
ab_count_get_guild_progress{method="GET"} 5 -> series_count=1
ab_count_get_guild_progress{method="POST"} 5 -> series_count=2
ab_sum_get_guild_progress{method="GET", service="guild"} 1 -> series_count=3 -
カスタムメトリクスは、環境ごとに最大1,000のアクティブシリーズに制限されています。この制限に達すると、新しいシリーズをプッシュできなくなります。
a. メトリクスは、一貫してスクレイプされ、Grafana Cloudによって受信される場合、アクティブシリーズと見なされます。
b. メトリクスは、20分間スクレイプされないか、Grafana Cloudによって受信されない場合、非アクティブシリーズと見なされます。
-
現在、メトリクスを表示するカスタムダッシュボードを作成することはできません。
-
カスタムメトリクスを含むExtendアプリメトリクスは、ポート8080の
/metricsエンドポイントで公開されます。この設定は、Extendアプリテンプレートを使用してExtendアプリを作成する際にデフォルトで設定されます。 -
以下の表は、カスタムメトリクスで使用できない予約済みラベルを示しています。これらのいずれかが使用された場合、事前定義された値に置き換えられます。
ラベルキー 値 説明 environment_name ${env_name}環境識別子名 product extend 製品識別子名: extend scenario ${extend_app_type}Extendアプリタイプ: function-override、event-handler、またはservice-extensionunion_namespace ${publisher_name}パブリッシャー名 game_namespace ${game_namespace}Extendアプリネームスペース app_name ${app_name}Extendアプリ名 job metric-services/extend-metrics 事前定義されたジョブ名 instance extend-metric-instance 事前定義されたインスタンス値
カスタムメトリクスに一意のプレフィックスを追加して、簡単に認識し、デフォルトメトリクスと区別できるようにします。例えば、ab_count_get_guild_progressでは、ab_が一意の識別子プレフィックスとして機能します。