Skip to content

Field 検証

DD の Field 検証サブシステムは、ログ書き込み前に構造化 Field のキー名を検証し、命名規則を強制するとともにセキュリティ保護を提供します。これにより、キーの不整合によるログ解析の困難さを防ぎ、Field キーを経由した悪意あるコンテンツの混入を阻止します。

検証モード

モード定数動作
オフ(デフォルト)FieldValidationNone検証なし。すべてのキーを許可
警告FieldValidationWarn規則に準拠しないキーは stderr に警告を出力。ログは書き込まれます
厳格FieldValidationStrict規則に準拠しないキーは stderr にエラーを出力。ログは書き込まれます

警告 ログメソッドはエラーを返しません

ログメソッド(InfoWith など)はエラーを返さないため、検証失敗は stderr 経由でのみ報告されます。厳格モードはログの書き込みを妨げませんが、stderr にエラーを明確に報告します。

命名規則

規則定数
任意(デフォルト)NamingConventionAnyスタイルチェックなし
snake_caseNamingConventionSnakeCaseuser_id, created_at
camelCaseNamingConventionCamelCaseuserId, createdAt
PascalCaseNamingConventionPascalCaseUserId, CreatedAt
kebab-caseNamingConventionKebabCaseuser-id, created-at

クイックスタート

オプション A:プリセット設定

go
package main

import (
    "log"

    "github.com/cybergodev/dd"
)

func main() {
    cfg := dd.DefaultConfig()
    cfg.FieldValidation = dd.StrictSnakeCaseConfig()
    // 以下と同等です:
    // &dd.FieldValidationConfig{
    //     Mode:                     dd.FieldValidationStrict,
    //     Convention:               dd.NamingConventionSnakeCase,
    //     AllowCommonAbbreviations: true,
    //     EnableSecurityValidation: true,
    // }

    logger, err := dd.New(cfg)
    if err != nil {
        log.Fatal(err)
    }
    defer logger.Close()

    logger.InfoWith("user action",
        dd.String("user_id", "123"),    // ✅ 有効な snake_case
        dd.String("userName", "alice"), // ⚠️ 無効、stderr にエラー出力
    )
}

オプション B:カスタム設定

go
cfg := dd.DefaultConfig()
cfg.FieldValidation = &dd.FieldValidationConfig{
    Mode:                     dd.FieldValidationWarn,
    Convention:               dd.NamingConventionCamelCase,
    AllowCommonAbbreviations: true,
    EnableSecurityValidation: true,
}

オプション C:ランタイム切り替え

go
// 厳格な snake_case を有効化
logger.SetFieldValidation(dd.StrictSnakeCaseConfig())

// 検証を無効化
logger.SetFieldValidation(nil)

// 現在の設定を照会
fv := logger.GetFieldValidation()

一般的な略語の除外

AllowCommonAbbreviations: true(プリセットのデフォルト)を設定すると、命名規則に厳密に一致しなくても、以下の略語が許可されます:

略語説明
id, url, uri, ip基本識別子
http, https, apiプロトコル & インターフェース
json, xml, html, sqlデータフォーマット
tcp, udp, ssl, tlsネットワークプロトコル
jwt, oauth認証
*_id, *_url, *_api など接尾辞の組み合わせ(例:user_id

セキュリティ検証

EnableSecurityValidation: true(プリセットのデフォルト)を設定すると、命名規則の検証前に以下のセキュリティチェックが実行されます:

チェック除去対象説明
Log4Shell 検出${jndi:ldap://...}ログキーを経由した JNDI インジェクションを防止
ホモグラフ検出ラテン文字 a の代わりにキリル文字 а視覚的偽装攻撃を防止
過長 UTF-8 エンコーディング最短形式以外のエンコーディングセキュリティフィルターのバイパスを防止

危険 ゼロ値の落とし穴

&dd.FieldValidationConfig{Mode: dd.FieldValidationStrict}EnableSecurityValidation の設定なしで使用すると、ゼロ値の false のままになり、セキュリティチェックが黙ってスキップされます。常に DefaultFieldValidationConfig() またはプリセット関数(StrictSnakeCaseConfig() など)を使用してください。これらはこのフィールドを true に設定します。

複数規則のプロジェクト

プロジェクトで Go バックエンド(snake_case)と JavaScript フロントエンド(camelCase)の両方のログがある場合、異なる規則を持つ異なる Logger を使用してください:

go
// バックエンド Logger:snake_case
backendCfg := dd.DefaultConfig()
backendCfg.FieldValidation = dd.StrictSnakeCaseConfig()
backendLogger, _ := dd.New(backendCfg)

// フロントエンドログ集約 Logger:camelCase
frontendCfg := dd.DefaultConfig()
frontendCfg.FieldValidation = dd.StrictCamelCaseConfig()
frontendLogger, _ := dd.New(frontendCfg)

検証ルール

各命名規則の具体的なルール:

規則ルール
snake_case小文字 + 数字 + アンダースコア。先頭/末尾に _ なし。連続する __ なし
camelCase文字 + 数字。最初の文字は小文字
PascalCase文字 + 数字。最初の文字は大文字
kebab-case小文字 + 数字 + ハイフン。先頭/末尾に - なし。連続する -- なし

次のステップ