Azure Functions(Linux/Java 17)から Application Insights にカスタム メトリックやトレースを送るうえで、ポータルを一切触らず Bicep だけで “Collection Level = Recommended” に相当する分散トレーシング設定を有効化する方法を、最小構成から運用の勘所までまとめました。既存の Application Insights 再利用パターンと新規作成パターンの双方を網羅し、確認手順・KQL・コード例まで一気通貫で解説します。
質問の要点と結論
- 課題:Java 17 の Azure Functions(Linux, Java)で、Application Insights にカスタム メトリック/トレースを送信したい。ポータル操作なし(Bicep のみ)で “Collection Level = Recommended” を有効化したい。既存の Application Insights を使い回す Bicep も知りたい。
- 結論(最短の答え):
- Application Insights リソース側に
CollectionLevelを設定する必要はありません。(Bicep では Unknown property 警告。削除して問題なし) - Function App 側で Java agent を有効化し、アプリ設定
APPLICATIONINSIGHTS_PREVIEW_FEATURES=recommendedを指定すれば、“Collection Level = Recommended” 相当がオンになります。 - 既存の Application Insights をexisting リソース参照でリンクし、
APPLICATIONINSIGHTS_CONNECTION_STRINGを Function App に渡します。
- Application Insights リソース側に
Bicep の基本方針(なぜこうするのか)
“コレクション レベル”は Application Insights リソースのプロパティではなく、アプリケーション プラットフォーム側のテレメトリ収集挙動(Java agent の有効化と動作モード)で決まります。Bicep で行うことは次の 2 点だけです。
- Function App に Java agent をアタッチ(App Service 上の自動アタッチ機能を使う)
- プレビュー機能を “recommended” で有効化(追加収集や推奨インストルメンテーションをオン)
この設計により、ポータルで「Application Insights を有効化」や「コレクション レベル変更」といった個別操作は不要になります。
最少構成:既存の Application Insights をリンクする Bicep
すでに運用中の Application Insights を再利用する最小テンプレートです。ポイントは existing 参照と Function App へのアプリ設定、そしてリンク用タグです。
@description('既存 Application Insights 名')
param appInsightsName string
@description('Function App 名')
param functionAppName string
param location string = resourceGroup().location
// 既存 Application Insights を参照
resource existingAI 'Microsoft.Insights/components@2020-02-02' existing = {
name: appInsightsName
}
// Function App 本体
resource functionApp 'Microsoft.Web/sites@2022-09-01' = {
name: functionAppName
location: location
kind: 'functionapp,linux,java'
identity: { type: 'SystemAssigned' }
properties: {
httpsOnly: true
siteConfig: {
appSettings: [
{ name: 'APPLICATIONINSIGHTS_CONNECTION_STRING'
value: existingAI.properties.ConnectionString }
{ name: 'APPLICATIONINSIGHTS_ENABLE_AGENT' value: 'true' }
{ name: 'APPLICATIONINSIGHTS_PREVIEW_FEATURES' value: 'recommended' }
{ name: 'APPLICATIONINSIGHTS_PROFILERFEATURE_VERSION' value: '1.0.0' }
{ name: 'FUNCTIONS_WORKER_RUNTIME' value: 'java' }
{ name: 'FUNCTIONS_EXTENSION_VERSION' value: '~4' }
// Linux の Java ランタイム指定(推奨)
{ name: 'JAVA_VERSION' value: '17' }
]
// Linux の明示指定をする場合は以下も(必要時のみ)
// linuxFxVersion: 'Java|17'
}
}
// Portal の関連付け表示用(運用時に便利)
tags: { 'hidden-link:${existingAI.id}': 'Resource' }
}
APPLICATIONINSIGHTS_PREVIEW_FEATURES=recommendedが“Collection Level = Recommended”同等のキー設定です。existingを付けないと既存 AI の再利用にならず、新規作成されてしまう点に注意。- Linux/Java では
kind: 'functionapp,linux,java'を明示し、必要に応じてlinuxFxVersionで Java 17 を固定化します。
フル構成:Log Analytics + Application Insights を新規作成してリンク
新規にワークスペース連携の Application Insights を用意するテンプレートです。再利用パターンとの違いは AI/LAW の生成とリンクだけで、Function App 側の設定は同じです。
@description('リソースのベース名(接頭辞)')
param baseName string
@description('デプロイ先ロケーション')
param location string = resourceGroup().location
var laName = '${baseName}-law'
var aiName = '${baseName}-ai'
var funcApp = '${baseName}-func'
resource la 'Microsoft.OperationalInsights/workspaces@2022-10-01' = {
name: laName
location: location
properties: {
retentionInDays: 30
features: {
enableLogAccessUsingOnlyResourcePermissions: true
}
}
}
resource ai 'Microsoft.Insights/components@2020-02-02' = {
name: aiName
location: location
kind: 'web'
properties: {
Application_Type: 'web'
WorkspaceResourceId: la.id
}
}
resource plan 'Microsoft.Web/serverfarms@2022-09-01' = {
name: '${baseName}-plan'
location: location
kind: 'functionapp'
sku: {
name: 'Y1'
tier: 'Dynamic' // Consumption
}
}
resource func 'Microsoft.Web/sites@2022-09-01' = {
name: funcApp
location: location
kind: 'functionapp,linux,java'
identity: { type: 'SystemAssigned' }
properties: {
serverFarmId: plan.id
httpsOnly: true
siteConfig: {
linuxFxVersion: 'Java|17'
appSettings: [
{ name: 'FUNCTIONS_EXTENSION_VERSION' value: '~4' }
{ name: 'FUNCTIONS_WORKER_RUNTIME' value: 'java' }
{ name: 'APPLICATIONINSIGHTS_CONNECTION_STRING' value: ai.properties.ConnectionString }
{ name: 'APPLICATIONINSIGHTS_ENABLE_AGENT' value: 'true' }
{ name: 'APPLICATIONINSIGHTS_PREVIEW_FEATURES' value: 'recommended' }
{ name: 'APPLICATIONINSIGHTS_PROFILERFEATURE_VERSION' value: '1.0.0' }
{ name: 'JAVA_VERSION' value: '17' }
// ビルド成果物の配布方式に応じて
// { name: 'WEBSITE_RUN_FROM_PACKAGE' value: '1' }
]
}
}
tags: {
'hidden-link:${ai.id}': 'Resource'
'hidden-link:${la.id}': 'Resource'
}
}
パラメータ ファイル例(.bicepparam)
using 'main.bicep'
param baseName = 'demoapp-jp'
param location = 'Japan East'
デプロイ コマンド例(Azure CLI)
az deployment group create \
--resource-group <rg-name> \
--template-file main.bicep \
--parameters main.bicepparam
アプリ設定(Application Settings)完全版チェックリスト
| キー | 必須 / 任意 | 推奨値 | 説明 |
|---|---|---|---|
APPLICATIONINSIGHTS_CONNECTION_STRING | 必須 | AI の接続文字列 | 既存/新規 AI を問わず Connection String を設定。InstrumentationKey より接続文字列の使用を推奨。 |
APPLICATIONINSIGHTS_ENABLE_AGENT | 必須 | true | Java agent の自動アタッチを有効化。分散トレーシングや依存関係収集のベースとなる。 |
APPLICATIONINSIGHTS_PREVIEW_FEATURES | 必須 | recommended | “Collection Level = Recommended” 相当をオン。綴りは 小文字のみで厳密に。 |
APPLICATIONINSIGHTS_PROFILERFEATURE_VERSION | 任意 | 1.0.0 | Profiler 機能の有効化に関連。組織ポリシーに合わせて使用。 |
APPLICATIONINSIGHTS_ROLE_NAME | 任意 | 例:my-func | AI の cloud_RoleName に反映。複数 Function App を 1 つの AI に集約する場合に可視性が向上。 |
FUNCTIONS_WORKER_RUNTIME | 必須 | java | Functions ランタイムの種類。 |
FUNCTIONS_EXTENSION_VERSION | 必須 | ~4 | Functions のメジャー バージョン。 |
JAVA_VERSION | 推奨 | 17 | Java の実行バージョンを明示。Linux の場合は linuxFxVersion: 'Java|17' の指定も可。 |
ネットワーク/セキュリティの注意点
Function App から Application Insights への送信はアウトバウンド HTTPS を前提とします。VNet 経由や NSG 制限を行う場合は、以下の先を遮断しないようにします。
| 用途 | ドメイン(例) | 備考 |
|---|---|---|
| テレメトリ取り込み | 接続文字列の IngestionEndpoint のホスト名(例:*.in.applicationinsights.azure.com) | 地域によりエンドポイントが異なるため、接続文字列の値を参照。 |
| 後方互換(旧来エンドポイント) | dc.services.visualstudio.com | 古いエージェント/SDK 互換のために記載。新規は上段の地域エンドポイントが基本。 |
| ライブ メトリクス等 | (AI ライブ機能関連のドメイン) | 組織要件に応じて開放を検討。不要なら閉じても可。 |
動作確認(KQL サンプル)
デプロイ直後は数分待つとテレメトリが到達します。次の Kusto クエリで “recommended” 相当の収集が効いているかを確認します。
// トレース(アプリログ)
traces
| where cloud_RoleName == "my-func" // APPLICATIONINSIGHTS_ROLE_NAME を設定した場合
| where timestamp > ago(30m)
| sort by timestamp desc
// 依存関係(HTTP 呼び出し・DB 等のオートインストルメンテーション)
dependencies
| where cloud_RoleName == "my-func"
| where timestamp > ago(30m)
| summarize count() by type, success
// カスタム メトリック(後述コード例で送信した名前に合わせる)
customMetrics
| where name == "orders.processed"
| summarize total = sum(value), dcount(cloud_RoleInstance) by bin(timestamp, 5m)
| order by timestamp desc
アプリからのカスタム メトリック送信(Java)
OpenTelemetry API(Java agent 併用)
Application Insights の Java agent は内部で OpenTelemetry を利用します。アプリ側は OTel API を使ってメトリック/トレースを生成すると、エージェント経由で AI へ輸送されます(追加の接続設定は不要)。
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.metrics.Meter;
import io.opentelemetry.api.metrics.LongCounter;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
public class MetricsExample {
private static final Meter meter =
GlobalOpenTelemetry.get().getMeter("com.example.func");
private static final LongCounter ordersProcessed =
meter.counterBuilder("orders.processed")
.setDescription("Number of processed orders")
.setUnit("1")
.build();
public static void track(String region) {
ordersProcessed.add(1, Attributes.of(AttributeKey.stringKey("region"), region));
}
}
GlobalOpenTelemetryを使うことで、Azure 側のエージェント設定をそのまま活用できます。- メトリック名は
lowercase.with.dotsなど機械可読な命名を推奨。ディメンションはAttributesに付与します。
TelemetryClient(Application Insights Java SDK)
エージェントと併用して、従来の SDK で明示的に送る方法です。既存資産の移行にも向きます。
import com.microsoft.applicationinsights.TelemetryClient;
import com.microsoft.applicationinsights.TelemetryConfiguration;
import com.microsoft.applicationinsights.telemetry.MetricTelemetry;
import java.util.HashMap;
import java.util.Map;
public class AiClassicExample {
private static final TelemetryClient client;
static {
TelemetryConfiguration cfg = TelemetryConfiguration.createDefault();
cfg.setConnectionString(System.getenv("APPLICATIONINSIGHTS_CONNECTION_STRING"));
client = new TelemetryClient(cfg);
}
public static void trackOrder(double amount, String region) {
MetricTelemetry metric = new MetricTelemetry("orders.amount", amount);
Map props = new HashMap<>();
props.put("region", region);
client.trackMetric(metric);
client.trackEvent("order.completed", props, null);
client.flush();
}
}
Micrometer(Spring ベースのユースケース)
Spring Boot を Functions で使う場合は Micrometer を経由すると、カウンタやタイマの定義が容易です。エージェントが有効なら OTel 経由で AI に流れます。
// 例:アプリ起動時にカウンタを登録し、ハンドラでインクリメント
Counter counter = Counter.builder("orders.processed")
.description("Number of processed orders")
.register(Metrics.globalRegistry);
public void handle(...) {
counter.increment();
}
運用ノウハウ(プラン/性能/コスト)
| 観点 | 推奨・注意点 |
|---|---|
| プラン選定 | 消費(Consumption)は低頻度ジョブやバーストに強い一方、コールドスタート時に Java agent の初期化で数秒遅延が出ることがあります。低レイテンシ要件なら Premium(EP)を検討。 |
| サンプリング | 既定の確率サンプリングでコスト抑制。高負荷時はサンプリングを前提にダッシュボードを設計し、重大アラート用データはメトリック中心に。 |
| ロール名の粒度 | APPLICATIONINSIGHTS_ROLE_NAME をサービス単位で付与し、ダッシュボード・アラートのスコープを明瞭化。 |
| ログ保持 | Log Analytics の保持日数(例:30 日)をワークロードに合わせて調整。Long-term 保持はアーカイブを活用。 |
よくあるハマりどころ(チェックリスト)
| 項目 | 確認内容 |
|---|---|
| 接続文字列 | APPLICATIONINSIGHTS_CONNECTION_STRING が意図した AIを指すか(ステージ/本番の取り違え注意)。 |
| プレビュー機能 | 値は厳密に recommended(小文字のみ)。Recommended は無効。 |
| ネットワーク制限 | VNet/NSG で IngestionEndpoint への 443 を開放。古い構成では dc.services.visualstudio.com も許可。 |
| Java ランタイム | Java 11/17 は AI Java agent 対応済み。ランタイムの明示固定(linuxFxVersion)でズレを防止。 |
| AI 側プロパティ | Application Insights リソースに CollectionLevel のようなプロパティを作らない(Unknown property)。 |
| 既存 AI の再利用 | existing 修飾子を付与。ないと新規作成される。 |
運用で効く設計パターン(Bicep の作法)
- 接続先の切り替えはパラメータ化:AI 名や Connection String を stage(dev/stg/prod) で差し替え。
- タグで資産追跡:
hidden-link:<resourceId>だけでなく、owner、costCenter、environmentを付与。 - アプリ設定はモジュール化:
appSettingsを配列変数でまとめ、ワークロード固有のキーのみ差し替え。 - フェイルセーフ:AI 未到達時もアプリが落ちない前提(送信失敗はリトライ/バックオフ)。
Windows(参考)との違い
Windows プランでも考え方は同じです。主な違いは以下の通りです。
| 観点 | Linux(本記事) | Windows(参考) |
|---|---|---|
| kind / ランタイム | 'functionapp,linux,java' / linuxFxVersion: 'Java|17' | 'functionapp' / siteConfig.javaVersion: '17' |
| Java agent | APPLICATIONINSIGHTS_ENABLE_AGENT=true | 同様に有効化 |
| ファイルシステム | 読み取り専用(Run From Package)推奨 | 同様だが一部ツール差異あり |
アラート/可観測性テンプレートのたたき台
“recommended” を有効化したら、以下の指標でまずアラート化しておくと運用が安定します。
- 失敗率:
requests | summarize failureRate = 100.0 * (sumif(itemCount, success==false) / sum(itemCount)) - 外形監視:Functions のトリガー別に遅延・エラー割合を可視化。
- 重要メトリック:ビジネス カウンタ(例:
orders.processed)の急減・急増検知。
トラブルシュート手順
- AI 到達確認:上記 KQL で直近 30 分の
traces/dependenciesを確認。ゼロ件ならネットワーク/接続文字列を再確認。 - アプリ設定の反映:再デプロイ後に Function App のリスタートを実施。設定のタイプミス(大文字混入)に注意。
- エージェント衝突:独自の OTel SDK 初期化とエージェントの二重初期化が競合しないかを確認。基本は
GlobalOpenTelemetryを利用。 - サンプリング影響:トレースはサンプリングで間引かれるため、メトリックは必ず送る設計にして可観測性を担保。
まとめ
“Collection Level = Recommended” を Bicep だけで成立させる鍵は、Function App に Java agent を有効化し、APPLICATIONINSIGHTS_PREVIEW_FEATURES=recommended を指定することです。Application Insights リソース側に CollectionLevel のような設定は不要で、既存インスタンスも existing 参照で安全に再利用できます。この記事のテンプレートとチェックリスト、KQL・コード例まで含めて適用すれば、ポータル操作なしで Java Functions の分散トレーシングとカスタム メトリック収集を“推奨レベル”で有効化し、運用の初期セットを自動化できます。
付録:デプロイ後の自己診断コマンド
# Function App のアプリ設定を確認(誤字の洗い出し)
az webapp config appsettings list \
--name <func-name> \
--resource-group <rg-name> \
--query "[?name=='APPLICATIONINSIGHTS_PREVIEW_FEATURES' || name=='APPLICATIONINSIGHTS_ENABLE_AGENT' || name=='APPLICATIONINSIGHTS_CONNECTION_STRING']"
# Java ランタイムの確認(Linux)
az webapp show
--name --resource-group
--query "siteConfig.linuxFxVersion"
付録:Bicep スニペット集(再利用可)
既存 AI をパラメータ化して読み込むモジュール
param aiName string
resource ai 'Microsoft.Insights/components@2020-02-02' existing = {
name: aiName
}
output aiConnectionString string = ai.properties.ConnectionString
output aiId string = ai.id
Function App のアプリ設定配列を共通化
param connectionString string
param javaVersion string = '17'
var baseAppSettings = [
{ name: 'FUNCTIONS_EXTENSION_VERSION' value: '~4' }
{ name: 'FUNCTIONS_WORKER_RUNTIME' value: 'java' }
{ name: 'JAVA_VERSION' value: javaVersion }
{ name: 'APPLICATIONINSIGHTS_CONNECTION_STRING' value: connectionString }
{ name: 'APPLICATIONINSIGHTS_ENABLE_AGENT' value: 'true' }
{ name: 'APPLICATIONINSIGHTS_PREVIEW_FEATURES' value: 'recommended' }
]
付録:Functions の Java ハンドラでの計測例
public class MyFunction {
@FunctionName("OrderProcessor")
public HttpResponseMessage run(
@HttpTrigger(name = "req", methods = {HttpMethod.POST}, authLevel = AuthorizationLevel.FUNCTION)
HttpRequestMessage<Optional<String>> request,
final ExecutionContext context) {
// OpenTelemetry を使ったカウンタ
MetricsExample.track("jp-east");
// 従来 SDK での補助的なイベント
AiClassicExample.trackOrder(42.0, "jp-east");
return request.createResponseBuilder(HttpStatus.OK)
.body("ok")
.build();
}
}
Q&A
- Q: ポータルで「Application Insights をオン」にする操作は不要ですか?
A: はい。Bicep で接続文字列と agent 設定を入れれば十分です。ポータル操作は省略できます。 - Q: 既存 AI と新規 AI をステージで切り替えたい。
A:existing参照/新規作成をモジュール化し、環境パラメータで分岐させるのが安全です。 - Q: カスタム メトリックが customMetrics に出ない。
A: エージェント起動直後は到達まで数分かかります。サンプリングはメトリックには通常適用されませんが、間違いがないか KQL で確認し、名前・単位・ディメンションの綴りを再点検してください。 - Q: コストを抑えたい。
A: メトリック中心の監視(少量のトレース)/サンプリング活用/保持期間の最適化で効果が出ます。
短い再掲:この記事の要点
- Application Insights に CollectionLevel は不要。Bicep で指定しない。
- Function App 側で
APPLICATIONINSIGHTS_ENABLE_AGENT=trueとAPPLICATIONINSIGHTS_PREVIEW_FEATURES=recommended。 - 既存 AI は
existing参照で安全に再利用。 - OpenTelemetry API/TelemetryClient/Micrometer いずれのコードパスでもカスタム メトリック送信可能。

コメント