すべてのプロダクト
Search
ドキュメントセンター

ApsaraVideo VOD:ログシステム

最終更新日:Sep 11, 2026

ログシステムは、AliPlayerKit の基本的なモジュールです。統一ログセンターである LogHub を使用して、ログ出力、レベルフィルタリング、オブザーバーメカニズムなどのコア機能を提供します。これにより、プレーヤーのランタイム情報における可視性とトレーサビリティを確保します。

概念

LogHub とは

LogHub は、AliPlayerKit のすべてのログ出力に対する統一されたエントリーポイントです。シングルトンパターンで設計されています。LogHub は、ネイティブの iOS ログ API である NSLog をカプセル化し、以下のコア機能を追加します:

機能

説明

ログスイッチ

ログ出力の有効/無効を制御します (マスタースイッチ)。

コンソールスイッチ

Xcode コンソールへのログ出力を制御します。

レベルフィルタリング

指定されたレベル以上のログのみを出力します。

オブザーバーメカニズム

外部のオブザーバーがログ出力を受信し、ファイルへの書き込みなどのカスタム処理を行えるようにします。

ログオブザーバーとは

ログオブザーバー (LogObserver) は、LogHub からログを受信するためのコールバックプロトコルです。このプロトコルを実装することで、ログの処理方法をカスタマイズできます。例:

  • テクニカルサポートチームがトラブルシューティングに使用できるよう、ログをファイルに書き込みます。

  • リモートログ収集を有効にするために、ログをリモートサーバーにアップロードします。

  • デバッグパネルを作成するために、ログを UI に表示します。

ハイブリッドスレッドモデル

LogHub はハイブリッドスレッドモデルを使用します:

操作

スレッド

スレッド名とタイムスタンプのキャプチャ

呼び出し側スレッドでの同期実行

コンソール出力 (NSLog)

呼び出し側スレッドでの同期実行

オブザーバー通知

バックグラウンドシリアルキューへの非同期ディスパッチ

説明

LogObserver.onLog: コールバックはバックグラウンドシリアルキューで実行されます。UI を更新するには、メインスレッドに切り替える必要があります。

機能

コア機能

機能

説明

マルチレベルロギング

Verbose、Debug、Info、Warn、Error の 5 レベルをサポートします。

三重制御

グローバルスイッチ、レベルフィルタリング、コンソールスイッチにより、出力範囲を精密に制御します。

オブザーバーメカニズム

ログの永続化やリモートレポートなどに使用するカスタムオブザーバーを登録できます。

ヘルパーマクロ

ソースコードの位置情報を自動的に取得する SLOGV/D/I/W/E マクロを提供します。

ログパネル

LogPanelSlot を使用して、プレーヤービュー内にログをリアルタイムで表示します (デバッグ専用)。

グローバルショートカット API

AliPlayerKit のクラスメソッドを使用して、ログレベルとコンソール出力をすばやく設定できます。

コアコンポーネント

コンポーネント

タイプ

説明

LogHub

シングルトン

ログ出力の統合エントリーポイントであるログセンターです。

LogLevel

列挙型

ログレベルの定義です。

LogInfo

データクラス

単一のログエントリの完全な情報をカプセル化したモデルです。

LogObserver

プロトコル

ログオブザーバーインターフェイスです。

LogPanelSlot

スロット

プレーヤーに組み込まれ、主要なログをリアルタイムで表示するログパネルです。

使用方法

基本的な使用方法:グローバルクイック設定

推奨される AliPlayerKit のクラスメソッドを使用して、ログシステムをすばやく設定できます:

// AppDelegate で、セットアップ後に設定します
[AliPlayerKit setup];

// ログレベルを設定します
[AliPlayerKit setLogLevel:LogLevelVerbose];

// コンソールログを有効または無効にします
[AliPlayerKit enableConsoleLog:YES];

AliPlayerKit メソッド

説明

setLogLevel:

ログレベルを設定します。このレベル未満のログは無視されます。デフォルトは LogLevelInfo です。

logLevel

現在のログレベルを取得します。

enableConsoleLog:

コンソール出力を有効または無効にします。デフォルトでは有効です。

isConsoleLogEnabled

コンソールログが有効かどうかを確認します。

setDebugModeEnabled:

デバッグモードを有効または無効にします。

isDebugModeEnabled

デバッグモードが有効かどうかを確認します。

setLogPanelEnabled:

ログパネルスロットを有効または無効にします。デフォルトでは無効です。

isLogPanelEnabled

ログパネルが有効かどうかを確認します。

基本的な使用方法:ログ出力

SLOG シリーズのヘルパーマクロを使用して、レベルごとにログを出力できます。これらのマクロは、ソースファイル名と行番号を自動的に取得します:

#import <AliPlayerKit/LogMacros.h>

// さまざまなレベルでログを出力します (__FILE_NAME__ と __LINE__ を自動的に取得します)
SLOGV(@"viewDidLoad called");
SLOGD(@"Configure player: videoId=%@", videoId);
SLOGI(@"Start playing video: %@", videoTitle);
SLOGW(@"Buffering, current progress: %.1f%%", progress * 100);
SLOGE(@"Playback failed, error code: %ld", (long)errorCode);

ヘルパーマクロの一覧:

マクロ

レベル

説明

SLOGV(fmt, ...)

詳細

最も詳細なログレベルです。

SLOGD(fmt, ...)

デバッグ

デバッグ情報です。

SLOGI(fmt, ...)

情報

一般的な情報です。

SLOGW(fmt, ...)

警告

潜在的な問題です。

SLOGE(fmt, ...)

エラー

エラーメッセージです。

説明

SLOG マクロは、LogHub の logLevel:file:line:message:error: メソッドを呼び出します。__FILE_NAME__ と __LINE__ を使用してソースコードの位置情報を自動的に取得するため、タグを手動で渡す必要はありません。

LogHub のインスタンスメソッドを直接呼び出し、タグを手動で指定することもできます:

// タグを使用してログの出力元を識別します
[[LogHub sharedHub] i:@"PlayerVC" msg:@"Start playback"];
[[LogHub sharedHub] e:@"MediaPlayer" msg:@"Playback failed" error:error];

基本的な使用方法:ログレベルの設定

LogHub を使用して、ログプロパティを直接設定できます:

LogHub *logHub = [LogHub sharedHub];

#ifdef DEBUG
    // 開発環境:詳細ログ + コンソール出力
    logHub.logEnabled = YES;
    logHub.consoleLogEnabled = YES;
    logHub.logLevel = LogLevelVerbose;
#else
    // 本番環境:簡潔なログ + コンソール出力を無効化
    logHub.logEnabled = YES;
    logHub.consoleLogEnabled = NO;
    logHub.logLevel = LogLevelInfo;
#endif

三重制御メカニズム:

制御レイヤー

プロパティ

説明

マスタースイッチ

logEnabled

無効にすると、オブザーバー通知を含むすべてのロギングが停止します。

レベルフィルタリング

logLevel

このレベル未満のログは無視されます。デフォルトは LogLevelInfo です。

コンソールスイッチ

consoleLogEnabled

NSLog を使用してログを Xcode コンソールに出力するかどうかを制御します。

説明

consoleLogEnabled を無効にした場合も、ログはオブザーバー通知を通じてディスパッチされますが、コンソール出力は抑止されます。logEnabled を無効にすると、すべてのログ要求が無視され、オブザーバーにも通知されません。

高度な使用方法:ログオブザーバーの登録

LogObserver プロトコルを実装することで、ログ処理をカスタマイズできます:

// ファイルログオブザーバーを作成して登録します
FileLogObserver *fileObserver = [[FileLogObserver alloc] init];
[[LogHub sharedHub] addObserver:fileObserver];

// 不要になったらオブザーバーを削除します
[[LogHub sharedHub] removeObserver:fileObserver];
説明

LogHub は、removeObserver: を使用して明示的に削除されるまで、オブザーバーへの強参照を保持します。循環参照を防ぐため、dealloc や viewWillDisappear: などの適切なタイミングで removeObserver: を呼び出す必要があります。

高度な使用方法:ログパネル

LogPanelSlot は、プレーヤービュー内に主要なログ情報をリアルタイムで表示する組み込みのデバッグ用スロットです:

// ログパネルを有効にします (デバッグ用途でのみ推奨)
[AliPlayerKit setLogPanelEnabled:YES];

操作

説明

タイトルバーをクリックする

ログ内容エリアを展開または折りたたみます。

[Clear] ボタンをクリックする

表示中のログをクリアします。

ログエリアを長押しする

ログ内容をクリップボードにコピーします。

説明

ログパネルに表示されるのはデバッグ以上のレベルのログのみです。setLogPanelEnabled: は rebuildSlots を呼び出す前に実行する必要があります。Minimal シナリオでは、パネルは表示されません。

カスタム開発

LogObserver プロトコル

@protocol LogObserver <NSObject>

@required

/// ログ出力コールバック
/// @param logInfo レベル、タグ、メッセージ、タイムスタンプ、スレッド名、ファイル名、行番号、およびエラー情報を含むログ情報オブジェクト。
/// @warning このコールバックはバックグラウンドシリアルキューで実行されます。UI を更新するには、メインスレッドにディスパッチしてください。
- (void)onLog:(LogInfo *)logInfo;

@end

LogInfo データモデル

プロパティ

タイプ

説明

level

LogLevel

ログレベル (読み取り専用)。

tag

NSString *

ログタグ (読み取り専用)。

message

NSString *

ログメッセージの内容 (読み取り専用)。

timestamp

NSDate *

ログ生成時のタイムスタンプ (読み取り専用)。

threadName

NSString *

ログを生成したスレッド名 (読み取り専用)。

fileName

NSString *

ソースファイル名。例:@"MyClass.m" (読み取り専用)。

line

NSInteger

ソースコードの行番号 (読み取り専用)。

error

NSError *

関連付けられたエラーオブジェクト。nil の場合もあります (読み取り専用)。

メソッド

説明

formattedString

整形済みのログ文字列を取得します。

initWithLevel:fileName:line:message:error:threadName:timestamp:

指定イニシャライザ。

initWithLevel:tag:message:

タイムスタンプ、スレッド名、ファイル名、および行番号を自動的に取得するコンビニエンスイニシャライザ。

整形後の出力形式:

2024-04-22 10:30:00.123 I/AliPlayerKit [version] [FileName:line] [threadName] : message

エラーがある場合は、さらに1行が追記されます:

Error: domain=xxx code=xxx userInfo=xxx

例:カスタムファイルログオブザーバー

以下は、ファイルログオブザーバーの完全な実装例です:

@interface MyFileLogObserver : NSObject <LogObserver>
- (instancetype)initWithLogDirectory:(NSString *)directory;
@end

@implementation MyFileLogObserver {
    NSString *_logFilePath;
    dispatch_queue_t _writeQueue;
    NSFileHandle *_fileHandle;
}

- (instancetype)initWithLogDirectory:(NSString *)directory {
    self = [super init];
    if (self) {
        _writeQueue = dispatch_queue_create("com.example.filelog",
                                            DISPATCH_QUEUE_SERIAL);
        [self setupLogFileAtDirectory:directory];
    }
    return self;
}

- (void)setupLogFileAtDirectory:(NSString *)directory {
    NSFileManager *fm = [NSFileManager defaultManager];
    if (![fm fileExistsAtPath:directory]) {
        [fm createDirectoryAtPath:directory
      withIntermediateDirectories:YES
                       attributes:nil
                            error:nil];
    }

    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    formatter.dateFormat = @"yyyy-MM-dd";
    NSString *fileName = [NSString stringWithFormat:@"player_%@.log",
                          [formatter stringFromDate:[NSDate date]]];
    _logFilePath = [directory stringByAppendingPathComponent:fileName];

    if (![fm fileExistsAtPath:_logFilePath]) {
        [fm createFileAtPath:_logFilePath contents:nil attributes:nil];
    }
    _fileHandle = [NSFileHandle fileHandleForWritingAtPath:_logFilePath];
    [_fileHandle seekToEndOfFile];
}

#pragma mark - LogObserver

- (void)onLog:(LogInfo *)logInfo {
    NSString *formatted = [logInfo formattedString];

    dispatch_async(_writeQueue, ^{
        NSString *line = [formatted stringByAppendingString:@"\n"];
        NSData *data = [line dataUsingEncoding:NSUTF8StringEncoding];
        @try {
            [self->_fileHandle writeData:data];
        } @catch (NSException *exception) {
            // 書き込み例外は無視します
        }
    });
}

- (void)dealloc {
    [_fileHandle closeFile];
}

@end
説明

onLog: コールバックはバックグラウンドシリアルキューで実行されます。ただし、ファイル I/O 操作では、ログのディスパッチキューのブロックを避けるため、別の書き込みキューを使用することを推奨します。キューをブロックすると、他のオブザーバーに影響する可能性があります。

例:完全な統合

// AppDelegate.m
#import <AliPlayerKit/AliPlayerKit.h>

@interface AppDelegate ()
@property (nonatomic, strong) MyFileLogObserver *fileLogObserver;
@end

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    // 1. AliPlayerKit を初期化します
    [AliPlayerKit setup];

    // 2. ログシステムを設定します
#ifdef DEBUG
    [AliPlayerKit setLogLevel:LogLevelVerbose];
    [AliPlayerKit enableConsoleLog:YES];
    // 任意:ログパネルを有効にします
    [AliPlayerKit setLogPanelEnabled:YES];
#else
    [AliPlayerKit setLogLevel:LogLevelInfo];
    [AliPlayerKit enableConsoleLog:NO];

    // 3. ファイルログオブザーバーを登録します (本番環境のみ)
    NSString *logDir = [NSSearchPathForDirectoriesInDomains(
        NSDocumentDirectory, NSUserDomainMask, YES).firstObject
        stringByAppendingPathComponent:@"PlayerLogs"];
    self.fileLogObserver = [[MyFileLogObserver alloc] initWithLogDirectory:logDir];
    [[LogHub sharedHub] addObserver:self.fileLogObserver];
#endif

    return YES;
}

@end
説明

PlayerKitUsages/UsageLogSystem モジュールには、ログシステムの使用方法を示す完全なサンプルが用意されています。このサンプルには、FileLogObserver と、ログを表示するための UI が含まれています。

ベストプラクティス

環境設定の推奨

環境

マスター スイッチ

コンソール

レベル

オブザーバー

ログ パネル

開発とデバッグ

YES

YES

Verbose

オプション (UI パネル)

オプション

内部テスト

YES

YES

Debug

ファイルロギング

NO

本番環境

YES

NO

Info

ファイルロギング + リモートレポーティング

NO

センシティブなシナリオ

NO

—

—

—

NO

一般的なエラー

エラー 1:オブザーバーコールバックでの UI の直接更新

// ✗ 誤り:onLog: はバックグラウンドシリアルキューで実行されます。UI を直接更新するとクラッシュが発生します。
- (void)onLog:(LogInfo *)logInfo {
    self.logLabel.text = [logInfo formattedString];  // クラッシュ!
}

// ✓ 正解:メインスレッドに切り替えて UI を更新します。
- (void)onLog:(LogInfo *)logInfo {
    NSString *formatted = [logInfo formattedString];
    dispatch_async(dispatch_get_main_queue(), ^{
        self.logLabel.text = formatted;
    });
}

エラー 2:オブザーバーでの同期ブロッキング操作

// ✗ 誤り:コールバックでファイルに同期的に書き込むと、ログディスパッチキューがブロックされます。
- (void)onLog:(LogInfo *)logInfo {
    NSString *log = [logInfo formattedString];
    [log writeToFile:path atomically:YES encoding:NSUTF8StringEncoding error:nil];
}

// ✓ 正解:ファイルに非同期で書き込みます。
- (void)onLog:(LogInfo *)logInfo {
    NSString *log = [logInfo formattedString];
    dispatch_async(_writeQueue, ^{
        // 非同期書き込み...
    });
}

エラー 3:オブザーバーの削除忘れによる循環参照

// ✗ 誤り:LogHub はオブザーバーを強参照します。削除しないと循環参照が発生します。
- (void)viewDidLoad {
    [[LogHub sharedHub] addObserver:self];
    // 解放されません...
}

// ✓ 正解:ライフサイクルの最後にオブザーバーを削除します。
- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    [[LogHub sharedHub] removeObserver:self];
}
説明

通知システムの Dispatcher とは異なり、LogHub はオブザーバーを強参照します。removeObserver: を呼び出さない場合、オブザーバーは解放されません。

API リファレンス

ログレベル (LogLevel)

レベル

列挙値

数値

説明

詳細

LogLevelVerbose

0

最も詳細で、開発とデバッグに使用します。

デバッグ

LogLevelDebug

1

デバッグ情報。

情報

LogLevelInfo

2

デフォルトレベル。本番環境に推奨されます。

警告

LogLevelWarn

3

潜在的な問題。

エラー

LogLevelError

4

エラーメッセージ。

なし

LogLevelNone

100

すべてのログを無効にします。

説明

LogLevel.h は、ログレベルを略語文字列 (V、D、I、W、E、または N) に変換する LogLevelToString() インライン関数も提供します。

LogHub コア API

プロパティ/メソッド

タイプ

説明

+sharedHub

クラスメソッド

シングルトンインスタンスを取得します。

logEnabled

BOOL

マスターログスイッチ (デフォルト: YES)。

logLevel

LogLevel

ログレベル (デフォルト: LogLevelInfo)。

consoleLogEnabled

BOOL

コンソールスイッチ (デフォルト: YES)。

v:msg:

インスタンスメソッド

詳細ログを出力します。

d:msg:

インスタンスメソッド

デバッグログを出力します。

i:msg:

インスタンスメソッド

情報ログを出力します。

w:msg:

インスタンスメソッド

警告ログを出力します。

e:msg:

インスタンスメソッド

エラーログを出力します。

e:msg:error:

インスタンスメソッド

NSError を含むエラーログを出力します。

log:tag:msg:

インスタンスメソッド

指定されたレベルでログを出力します。

logLevel:file:line:message:error:

インスタンスメソッド

コアロギングメソッド (SLOG マクロで使用されます)。

addObserver:

インスタンスメソッド

オブザーバーを追加します (強参照、重複して追加しても効果はありません)。

removeObserver:

インスタンスメソッド

オブザーバーを削除します。

+levelToString:

クラスメソッド

レベルを文字列 (V/D/I/W/E/N) に変換します。

+stringToLevel:

クラスメソッド

文字列をレベルに変換します (大文字と小文字を区別せず、認識できない場合は LogLevelInfo を返します)。

AliPlayerKit ログショートカット API

メソッド

説明

+setLogLevel:

ログレベルを設定します (setup の後に呼び出す必要があります)。

+logLevel

現在のログレベルを取得します。

+enableConsoleLog:

コンソールログ出力を有効または無効にします。

+isConsoleLogEnabled

コンソールログ出力が有効かどうかを確認します。

+setDebugModeEnabled:

デバッグモードを有効または無効にします。

+isDebugModeEnabled

デバッグモードが有効かどうかを確認します。

+setLogPanelEnabled:

ログパネルスロットを有効または無効にします。

+isLogPanelEnabled

ログパネルが有効かどうかを確認します。

SLOG ヘルパーマクロ

マクロ

レベル

展開形

SLOGV(fmt, ...)

詳細

[[LogHub sharedHub] logLevel:LogLevelVerbose file:@(__FILE_NAME__) line:__LINE__ message:... error:nil]

SLOGD(fmt, ...)

デバッグ

上記と同様、レベルは Debug です。

SLOGI(fmt, ...)

情報

上記と同様、レベルは Info です。

SLOGW(fmt, ...)

警告

上記と同様、レベルは Warn です。

SLOGE(fmt, ...)

エラー

上記と同様、レベルは Error です。

LogInfo プロパティ

プロパティ

タイプ

説明

level

LogLevel

ログレベル。

tag

NSString *

ログタグ。

message

NSString *

ログメッセージの内容。

timestamp

NSDate *

ログが生成されたタイムスタンプ。

threadName

NSString *

スレッド名。

fileName

NSString *

ソースファイル名。

line

NSInteger

ソースコードの行番号。

error

NSError *

関連するエラーオブジェクト (nil 許容)。

formattedString

NSString *

フォーマットされたログ文字列を取得します。

LogObserver プロトコル

メソッド

必須

説明

onLog:

はい (@required)

ログ出力コールバック。バックグラウンドシリアルキューで実行されます。