# util/libsrc/util/trace-provider.c

# 1 ファイル

## 1.1 util/libsrc/util/trace-provider.c

# 2 関数

## 2.1 to_syslog_level

    static int to_syslog_level ( enum trace_level lv )

enum trace_level を syslog severity に変換する。

## 2.2 get_process_basename

    static const char *get_process_basename ( char *buf, size_t buf_size )

自プロセスの実行ファイル名 (ベースネーム) を取得する。

### 2.2.1 引数

- buf [out] パス格納バッファ。
- buf_size [in] バッファサイズ。

### 2.2.2 戻り値

ベースネームへのポインタ (buf 内または FALLBACK_NAME)。

## 2.3 config_lock_exclusive

    static void config_lock_exclusive ( trace_provider_t *handle )

設定・状態変更用の排他ロックを取得する。 trace_start / trace_stop / trace_modify_* / trace_dispose で使用する。

## 2.4 config_unlock_exclusive

    static void config_unlock_exclusive ( trace_provider_t *handle )

排他ロックを解放する。

## 2.5 config_lock_shared_timed

    static int config_lock_shared_timed ( trace_provider_t *handle )

書き込み系 API 用の共有ロックをタイムアウト付きで取得する。 複数スレッドが同時に取得できる。 排他ロック保持中はブロックするが、LOCK_TIMEOUT_MS 経過で諦める。

### 2.5.1 戻り値

取得成功: 0 / タイムアウト: -1。

## 2.6 config_unlock_shared

    static void config_unlock_shared ( trace_provider_t *handle )

共有ロックを解放する。

## 2.7 build_effective_name

    static char *build_effective_name ( const char *name, int64_t identifier )

name と identifier から有効識別名 (effective name) を生成する。

name == NULL の場合はプロセスのベースネームを使用する。
identifier == 0 の場合は name をそのままコピーして返す。
identifier > 0 の場合は “-” を生成して返す。
戻り値はヒープ上に確保されるため、呼び出し元が free する必要がある。

### 2.7.1 戻り値

ヒープ上に確保された有効識別名。失敗時 NULL。

## 2.8 trace_init

    trace_provider_t *TRACE_UTIL_API trace_init ( void )

トレースプロバイダを初期化する。

自プロセスの実行ファイル名をデフォルト識別名として初期化します (例: Linux `/usr/bin/myapp` → `"myapp"`, Windows `C:\bin\myapp.exe` → `"myapp.exe"`)。
プロセス名の取得に失敗した場合は `"unknown"` を使用します。
Linux 環境では syslog を LOG_USER facility で初期化します。
Windows 環境ではライブラリ内蔵の ETW デフォルトプロバイダ (`TRACE_DEFAULT_PROVIDER_NAME`) を使用します。
識別名を変更するには trace_modify_name を呼び出してください。

### 2.8.1 戻り値

成功時: ハンドル (stopped 状態)。失敗時: NULL。

### 2.8.2 事後条件

戻り値のハンドルは stopped 状態です。 出力関数を使用するには trace_start を呼び出してください。
stopped 状態では設定関数 (trace_modify_name, trace_modify_ostrc, trace_modify_filetrc, trace_modify_stderrtrc) をスレッド安全に使用できます。

### 2.8.3 使用例

    trace_provider_t *logger = trace_init();
    trace_modify_name(logger, "myapp", 0);
    trace_start(logger);
    trace_write(logger, TRACE_LV_INFO, "application started");
    trace_stop(logger);
    trace_dispose(logger);

### 2.8.4 スレッド セーフティ

本関数はスレッドセーフです。
複数スレッドから独立したハンドルを取得するために並行して呼び出すことができます。

## 2.9 trace_start

    int TRACE_UTIL_API trace_start ( trace_provider_t *handle )

トレースプロバイダを開始する。

ハンドルを実行中 (started) 状態に遷移させます。
started 状態では出力関数 (trace_write 等) が有効になり、 設定関数 (trace_modify_name, trace_modify_ostrc, trace_modify_filetrc, trace_modify_stderrtrc) は使用できなくなります (-1 を返します)。
既に started 状態の場合は何もせず 0 を返します (冪等)。

### 2.9.1 引数

- handle [in] trace_init の戻り値。

### 2.9.2 戻り値

成功 0 / 失敗 -1。

### 2.9.3 警告

handle が NULL の場合は -1 を返します。

### 2.9.4 スレッド セーフティ

本関数はスレッドセーフです。
内部で排他制御を行います。

### 2.9.5 参照

trace_stop

## 2.10 trace_stop

    int TRACE_UTIL_API trace_stop ( trace_provider_t *handle )

トレースプロバイダを停止する。

ハンドルを停止中 (stopped) 状態に遷移させます。
stopped 状態では出力関数 (trace_write 等) は -1 を返し、 設定関数 (trace_modify_name, trace_modify_ostrc, trace_modify_filetrc, trace_modify_stderrtrc) がスレッド安全に使用できるようになります。
既に stopped 状態の場合は何もせず 0 を返します (冪等)。

### 2.10.1 引数

- handle [in] trace_init の戻り値。

### 2.10.2 戻り値

成功 0 / 失敗 -1。

### 2.10.3 警告

handle が NULL の場合は -1 を返します。

### 2.10.4 スレッド セーフティ

本関数はスレッドセーフです。
内部で排他制御を行います。

### 2.10.5 参照

trace_start

## 2.11 utf8_safe_truncate

    static size_t utf8_safe_truncate ( const char *s, size_t pos )

UTF-8 安全な切り詰め位置を返す。

pos バイト目以前で、UTF-8 マルチバイトシーケンスの途中を 避けた安全な切断位置を返す。

## 2.12 write_to_provider

    static int write_to_provider ( trace_provider_t *handle, enum trace_level level, const char *msg )

下層プロバイダに文字列を書き込む (内部ヘルパー)。

## 2.13 should_output

    static int should_output ( enum trace_level msg_level, enum trace_level threshold )

メッセージレベルがスレッショルド以内かを判定する。

### 2.13.1 戻り値

出力すべき場合は 1、そうでなければ 0。

## 2.14 write_stderr_entry

    static void write_stderr_entry ( enum trace_level level, const char *msg )

stderr にタイムスタンプ + レベル文字 + メッセージを 1 行書き込む。

ファイルトレースと同一フォーマット: “YYYY-MM-DD HH:MM:SS.mmm L msg”
タイムスタンプは UTC。fprintf(stderr) は MT-Safe のため追加ロック不要。

## 2.15 write_dual

    static int write_dual ( trace_provider_t *handle, enum trace_level level, const char *msg )

OS プロバイダとファイルプロバイダの両方へメッセージを書き込む。

レベルフィルタリングを行い、各出力先の条件に合致する場合のみ書き込む。 両方とも出力不要の場合は何もしない。

### 2.15.1 戻り値

成功 0 / いずれかの書き込み失敗 -1。

## 2.16 trace_write

    int TRACE_UTIL_API trace_write ( trace_provider_t *handle, enum trace_level level, const char *message )

トレースメッセージを書き込む。

指定されたトレースレベルでメッセージを書き込みます。
内部で enum trace_level を ETW Level または syslog severity に マッピングして書き込みます。

### 2.16.1 引数

- handle [in] trace_init の戻り値。
- level [in] トレースレベル (enum trace_level)。
- message [in] null 終端 UTF-8 文字列。

### 2.16.2 戻り値

成功 0 / 失敗 -1。

### 2.16.3 補足

メッセージが `TRACE_MESSAGE_MAX_BYTES` (1,024) バイト (null 終端含む) を超える場合、本関数は内部で 1,023 バイト以内に切り詰めて下層 API に渡します。
切り詰め時は UTF-8 マルチバイト文字の途中で切断しないよう バイト境界を調整します。
この上限は ETW (約 65,000 バイト) と syslog (RFC 3164: 1,024 バイト) の推奨値のうち小さい方に合わせています。

### 2.16.4 警告

handle が NULL の場合は何もせず 0 を返します。
message が NULL の場合は何もせず 0 を返します。
stopped 状態では -1 を返します。

### 2.16.5 事前条件

ハンドルが started 状態であること (trace_start 呼び出し済み)。 stopped 状態では -1 を返します。

### 2.16.6 スレッド セーフティ

本関数はスレッドセーフです。
started 状態では複数スレッドから並行して呼び出すことができます。

## 2.17 trace_writef

    int TRACE_UTIL_API trace_writef ( trace_provider_t *handle, enum trace_level level, const char *format, ... )

printf 形式でトレースメッセージを書き込む。

フォーマット文字列と可変長引数で構成されたメッセージを書き込みます。
内部で `vsnprintf` を使用し、`TRACE_MESSAGE_MAX_BYTES` (1,024) バイトの バッファにフォーマットします。バッファを超える部分は切り詰められます。

### 2.17.1 引数

- handle [in] trace_init の戻り値。
- level [in] トレースレベル (enum trace_level)。
- format [in] printf 形式のフォーマット文字列。
- … [in] フォーマット文字列に対応する可変長引数。

### 2.17.2 戻り値

成功 0 / 失敗 -1。

### 2.17.3 警告

handle が NULL の場合は何もせず 0 を返します。
format が NULL の場合は何もせず 0 を返します。
stopped 状態では -1 を返します。

### 2.17.4 事前条件

ハンドルが started 状態であること (trace_start 呼び出し済み)。 stopped 状態では -1 を返します。

### 2.17.5 使用例

    trace_writef(logger, TRACE_LV_INFO, "user=%s count=%d", username, count);

### 2.17.6 スレッド セーフティ

本関数はスレッドセーフです。
started 状態では複数スレッドから並行して呼び出すことができます。

## 2.18 hex_write_impl

    static int hex_write_impl ( trace_provider_t *handle, enum trace_level level, const void *data, size_t size, const char *label )

HEX ダンプ出力の内部実装。

ラベルは呼び出し元で事前にフォーマット済みの文字列を受け取る。 データが収まらない場合は切り詰めて “…” を付与する。 呼び出し元が共有ロックを保持した状態で呼ぶこと。

## 2.19 trace_hex_write

    int TRACE_UTIL_API trace_hex_write ( trace_provider_t *handle, enum trace_level level, const void *data, size_t size, const char *message )

バイナリデータを HEX テキスト形式でトレースに書き込む。

バイナリデータを大文字スペース区切りの HEX 文字列に変換して トレースに書き込みます。`message` が非 NULL の場合はラベルとして 先頭に付与されます。
ラベルなしの場合、最大 `TRACE_HEX_MAX_DATA_BYTES` (341) バイトの バイナリデータを出力できます。ラベル指定時はラベル長 + セパレータ (“:”, 2 バイト) 分だけ出力可能なデータ量が減少します。
データが収まらない場合は切り詰め、末尾に `"..."` を付与します。

### 2.19.1 引数

- handle [in] trace_init の戻り値。
- level [in] トレースレベル (enum trace_level)。
- data [in] バイナリデータへのポインタ。
- size [in] バイナリデータのバイト数。
- message [in] HEX データの手前に付与するラベル文字列。 NULL の場合はラベルなしで HEX のみ出力します。

### 2.19.2 戻り値

成功 0 / 失敗 -1。

### 2.19.3 警告

handle が NULL の場合は何もせず 0 を返します。
data が NULL の場合は何もせず 0 を返します。
size が 0 の場合は何もせず 0 を返します。
stopped 状態では -1 を返します。

### 2.19.4 事前条件

ハンドルが started 状態であること (trace_start 呼び出し済み)。 stopped 状態では -1 を返します。

### 2.19.5 出力フォーマット

    // message 指定あり (全データ表示):
    "Received data: 48 65 6C 6C 6F"

    // message が NULL (全データ表示):
    "48 65 6C 6C 6F"

    // データが収まらない場合 (切り詰め):
    "Received data: 48 65 6C ..."

### 2.19.6 スレッド セーフティ

本関数はスレッドセーフです。
started 状態では複数スレッドから並行して呼び出すことができます。

## 2.20 trace_hex_writef

    int TRACE_UTIL_API trace_hex_writef ( trace_provider_t *handle, enum trace_level level, const void *data, size_t size, const char *format, ... )

バイナリデータを HEX テキスト形式でトレースに書き込む (printf 形式ラベル)。

trace_hex_write と同等ですが、ラベル文字列を printf 形式の フォーマット文字列と可変長引数で指定できます。

### 2.20.1 引数

- handle [in] trace_init の戻り値。
- level [in] トレースレベル (enum trace_level)。
- data [in] バイナリデータへのポインタ。
- size [in] バイナリデータのバイト数。
- format [in] printf 形式のフォーマット文字列 (ラベル)。 NULL の場合はラベルなしで HEX のみ出力します。
- … [in] フォーマット文字列に対応する可変長引数。

### 2.20.2 戻り値

成功 0 / 失敗 -1。

### 2.20.3 警告

handle が NULL の場合は何もせず 0 を返します。
data が NULL の場合は何もせず 0 を返します。
size が 0 の場合は何もせず 0 を返します。
stopped 状態では -1 を返します。

### 2.20.4 事前条件

ハンドルが started 状態であること (trace_start 呼び出し済み)。 stopped 状態では -1 を返します。

### 2.20.5 出力フォーマット

    // フォーマット済みラベル付き:
    "packet[3]: 48 65 6C 6C 6F"

    // データが収まらない場合:
    "packet[3]: 48 65 6C ..."

### 2.20.6 使用例

    trace_hex_writef(logger, TRACE_LV_INFO, data, len, "packet[%d]", index);

### 2.20.7 スレッド セーフティ

本関数はスレッドセーフです。
started 状態では複数スレッドから並行して呼び出すことができます。

### 2.20.8 参照

trace_hex_write

## 2.21 trace_dispose

    void TRACE_UTIL_API trace_dispose ( trace_provider_t *handle )

トレースプロバイダを終了し、リソースを解放する。

ハンドルが NULL の場合は何もしません。
started 状態のハンドルに対しても呼び出し可能です (内部で自動的に停止してから解放します)。

### 2.21.1 引数

- handle [in] trace_init の戻り値。

### 2.21.2 スレッド セーフティ

本関数はスレッドセーフです。
本関数を呼び出した時点で進行中の trace_write 等が完了するまで待機してから リソースを解放します。
本関数呼び出し後、handle は無効となります。

## 2.22 trace_modify_name

    int TRACE_UTIL_API trace_modify_name ( trace_provider_t *handle, const char *name, int64_t identifier )

トレースプロバイダの識別名と識別番号を設定する。

初期化済みのハンドルを維持したまま、識別名と識別番号を変更します。
内部識別名は `name` と `identifier` から以下のルールで生成します。

- `identifier``==``0` : 識別名 = `name` そのもの

- `identifier``>``0` : 識別名 = `"<name>-<identifier>"` (ハイフン区切り)

- `identifier``<``0` : -1 を返す (無効値)
  Linux 環境では内部で closelog / openlog が呼び出されます。
  Windows 環境では ETW イベントの “Service” フィールド値のみが変更されます。

### 2.22.1 引数

- handle [in] trace_init の戻り値。
- name [in] ベース識別名。
  NULL の場合は自プロセスの実行ファイル名を使用します (trace_init と同じ動作)。
- identifier [in] アプリケーション管理識別番号 (0 以上)。
  0 の場合は `name` をそのまま使用します。
  正の値の場合は `"<name>-<identifier>"` を識別名とします。
  負の値の場合は -1 を返します。

### 2.22.2 戻り値

成功 0 / 失敗 (無効な引数・メモリ確保失敗等) -1。

### 2.22.3 警告

handle が NULL の場合は -1 を返します。
identifier に負の値を指定した場合は -1 を返します。
started 状態では -1 を返します。

### 2.22.4 事前条件

ハンドルが stopped 状態であること。 started 状態では -1 を返します。

### 2.22.5 使用例

    trace_provider_t *logger = trace_init();
    trace_modify_name(logger, "worker", 2); // 識別名 = "worker-2"
    trace_start(logger);
    trace_write(logger, TRACE_LV_INFO, "running as worker-2");
    trace_dispose(logger);

### 2.22.6 スレッド セーフティ

stopped 状態ではスレッドセーフです。
内部で排他制御を行います。

## 2.23 trace_modify_ostrc

    int TRACE_UTIL_API trace_modify_ostrc ( trace_provider_t *handle, enum trace_level level )

OS トレースのスレッショルドレベルを設定する。

ETW (Windows) または syslog (Linux) に出力するメッセージの 最低重要度レベルを変更します。
デフォルト値は `TRACE_DEFAULT_OS_LEVEL` (TRACE_LV_INFO) です。
`TRACE_LV_NONE` を指定すると OS トレース出力を完全に抑止します。

### 2.23.1 引数

- handle [in] trace_init の戻り値。
- level [in] 新しいスレッショルドレベル (enum trace_level)。

### 2.23.2 戻り値

成功 0 / 失敗 -1。

### 2.23.3 警告

handle が NULL の場合は -1 を返します。
started 状態では -1 を返します。

### 2.23.4 事前条件

ハンドルが stopped 状態であること。 started 状態では -1 を返します。

### 2.23.5 スレッド セーフティ

stopped 状態ではスレッドセーフです。
内部で排他制御を行います。

## 2.24 trace_modify_filetrc

    int TRACE_UTIL_API trace_modify_filetrc ( trace_provider_t *handle, const char *path, enum trace_level level, size_t max_bytes, int generations )

ファイルトレースの出力先と設定を変更する。

ファイルトレースを有効化または再構成します。
`path` に NULL を指定するとファイルトレースを無効化します (既存のファイルプロバイダを解放して閉じます)。
既にファイルトレースが有効な場合は既存のプロバイダを解放してから 新しいプロバイダを初期化します。
デフォルトのファイルトレースレベルは `TRACE_DEFAULT_FILE_LEVEL` (TRACE_LV_ERROR) です。
ファイルトレースは trace_init の直後は無効 (パス未指定) です。

### 2.24.1 引数

- handle [in] trace_init の戻り値。
- path [in] 出力ファイルパス。NULL の場合はファイルトレースを無効化。
- level [in] ファイルトレースのスレッショルドレベル (enum trace_level)。
- max_bytes [in] 1 ファイルあたりの最大バイト数。0 で既定値 (TRACE_FILE_DEFAULT_MAX_BYTES = 10 MB) を使用。
- generations [in] 保持する旧世代数。0 以下で既定値 (TRACE_FILE_DEFAULT_GENERATIONS = 5) を使用。

### 2.24.2 戻り値

成功 0 / 失敗 -1。

### 2.24.3 警告

handle が NULL の場合は -1 を返します。
started 状態では -1 を返します。
path に指定したファイルが書き込み不可の場合は -1 を返します。

### 2.24.4 事前条件

ハンドルが stopped 状態であること。 started 状態では -1 を返します。

### 2.24.5 スレッド セーフティ

stopped 状態ではスレッドセーフです。
内部で排他制御を行います。

## 2.25 trace_modify_stderrtrc

    int TRACE_UTIL_API trace_modify_stderrtrc ( trace_provider_t *handle, enum trace_level level )

stderr トレースのスレッショルドレベルを設定する。

標準エラー出力 (stderr) に出力するメッセージの最低重要度レベルを変更します。
出力フォーマットはファイルトレースと同一です。

    2026-04-02 12:34:56.789 I メッセージテキスト

タイムスタンプは UTC です。
デフォルト値は `TRACE_DEFAULT_STDERR_LEVEL` (TRACE_LV_NONE: 無効) です。
`TRACE_LV_NONE` を指定すると stderr 出力を完全に抑止します。

### 2.25.1 引数

- handle [in] trace_init の戻り値。
- level [in] 新しいスレッショルドレベル (enum trace_level)。

### 2.25.2 戻り値

成功 0 / 失敗 -1。

### 2.25.3 警告

handle が NULL の場合は -1 を返します。
started 状態では -1 を返します。

### 2.25.4 事前条件

ハンドルが stopped 状態であること。 started 状態では -1 を返します。

### 2.25.5 スレッド セーフティ

stopped 状態ではスレッドセーフです。
内部で排他制御を行います。

## 2.26 trace_get_ostrc

    enum trace_levelTRACE_UTIL_API trace_get_ostrc ( trace_provider_t *handle )

OS トレースの現在のスレッショルドレベルを取得する。

### 2.26.1 引数

- handle [in] trace_init の戻り値。

### 2.26.2 戻り値

現在のスレッショルドレベル。handle が NULL またはロック取得失敗時は `TRACE_LV_NONE` を返す。

### 2.26.3 スレッド セーフティ

本関数はスレッドセーフです。
started / stopped どちらの状態でも呼び出し可能です。

## 2.27 trace_get_filetrc

    enum trace_levelTRACE_UTIL_API trace_get_filetrc ( trace_provider_t *handle )

ファイルトレースの現在のスレッショルドレベルを取得する。

### 2.27.1 引数

- handle [in] trace_init の戻り値。

### 2.27.2 戻り値

現在のスレッショルドレベル。handle が NULL またはロック取得失敗時は `TRACE_LV_NONE` を返す。

### 2.27.3 スレッド セーフティ

本関数はスレッドセーフです。
started / stopped どちらの状態でも呼び出し可能です。

## 2.28 trace_get_stderrtrc

    enum trace_levelTRACE_UTIL_API trace_get_stderrtrc ( trace_provider_t *handle )

stderr トレースの現在のスレッショルドレベルを取得する。

### 2.28.1 引数

- handle [in] trace_init の戻り値。

### 2.28.2 戻り値

現在のスレッショルドレベル。handle が NULL またはロック取得失敗時は `TRACE_LV_NONE` を返す。

### 2.28.3 スレッド セーフティ

本関数はスレッドセーフです。
started / stopped どちらの状態でも呼び出し可能です。

# 3 変数

## 3.1 hex_chars

    static const char[] hex_chars = "0123456789ABCDEF";

HEX 変換用テーブル。

# 4 定数、マクロ

## 4.1 FALLBACK_NAME

    #define FALLBACK_NAME "unknown"

プロセス名取得失敗時のフォールバック名。

## 4.2 LOCK_TIMEOUT_MS

    #define LOCK_TIMEOUT_MS 100

共有ロック取得のタイムアウト (ミリ秒)。

## 4.3 MAX_BODY

    #define MAX_BODY (TRACE_MESSAGE_MAX_BYTES - 1)

切り詰め後の本文最大バイト数 (null 終端を除く)。

## 4.4 STDERR_TS_BUF_SIZE

    #define STDERR_TS_BUF_SIZE 24

stderr タイムスタンプバッファサイズ (“YYYY-MM-DD HH:MM:SS.mmm\0” = 24)。

## 4.5 ELLIPSIS_LEN

    #define ELLIPSIS_LEN 3

“…” サフィックスの長さ。

# 5 クラス/構造体

## 5.1 trace_provider

    struct trace_provider {
        int64_t identifier;
        syslog_provider_t *syslog_handle;
        enum trace_level os_level;
        enum trace_level file_level;
        trace_file_provider_t *file_handle;
        enum trace_level stderr_level;
        volatile int running;
        pthread_rwlock_t config_rwlock;
        int config_rwlock_initialized;
        int _pad_end;
    }

トレースプロバイダハンドル構造体 (内部定義)。

### 5.1.1 属性

#### 5.1.1.1 identifier

    int64_t identifier;

アプリケーション管理識別番号 (診断用)。0 = 識別番号なし。

#### 5.1.1.2 syslog_handle

    syslog_provider_t *syslog_handle;

syslog プロバイダハンドル (Linux)。

#### 5.1.1.3 os_level

    enum trace_level os_level;

OS トレース (ETW/syslog) のスレッショルドレベル。デフォルト: TRACE_LV_INFO。

#### 5.1.1.4 file_level

    enum trace_level file_level;

ファイルトレースのスレッショルドレベル。デフォルト: TRACE_LV_ERROR。

#### 5.1.1.5 file_handle

    trace_file_provider_t *file_handle;

ファイルトレースプロバイダハンドル。NULL = ファイルトレース無効。

#### 5.1.1.6 stderr_level

    enum trace_level stderr_level;

stderr トレースのスレッショルドレベル。デフォルト: TRACE_LV_NONE。

#### 5.1.1.7 running

    volatile int running;

実行状態フラグ (0=停止中, 1=実行中)。

#### 5.1.1.8 config_rwlock

    pthread_rwlock_t config_rwlock;

読み書きロック。write 系は共有ロック、設定変更・stop・dispose は排他ロック。

#### 5.1.1.9 config_rwlock_initialized

    int config_rwlock_initialized;

config_rwlock が初期化済みかどうかのフラグ。

#### 5.1.1.10 _pad_end

    int _pad_end;

パディング (構造体サイズを 8 バイト境界に揃える)。