nebula-logger-plugin-development について
Salesforce Apex で Nebula Logger のプラグインを開発するためのガイドです。トリガーとバッチの拡張ポイント、メタデータ登録、構成、実行順序、テストを説明し、フレームワークは unlocked package でのみ利用できます。
主な機能
- 01Apex のトリガー/バッチインターフェース
- 02カスタムメタデータによる登録
- 03実行順序とプラグイン構成
- 04プロジェクト構成とパッケージ化の指針
- 05テスト方法とリリースチェックリスト
活用シーン
- 01トリガー処理でログレコードを拡充
- 02ログ削除前のアーカイブやポリシー適用
- 03新規ログ向け外部通知の登録
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ jongpie/ nebulalogger --skill nebula-logger-plugin-developmentインストール後、Claude Code で/nebula-logger-plugin-developmentを入力して読み込まれたか確認します。
詳細
Nebula Logger 用プラグインの構築
パッケージの互換性
プラグインフレームワークはアンロックパッケージでのみ利用できます。マネージドパッケージ(名前空間 Nebula)では、現在プラグイン拡張ポイントを公開していません。
プラグインを作成する場合は、アンロックパッケージをインストールしてください。選択については、nebula-logger-install を参照してください。
LoggerPlugin、LoggerPlugin.Triggerable、LoggerPlugin.Batchable、LoggerTriggerableContext、LoggerBatchableContext はすべて global ではなく public である点に注意してください。このスキルコレクションの他の箇所では、「global のみを使用する」という方針を案内しています(nebula-logger-instrumentation の「サポート対象の API サーフェス」セクションを参照)。プラグインフレームワークは意図的な例外です。拡張ポイントは、アンロックパッケージ自身のコンパイル単位内でのみアクセス可能なため、public になっています。他の public サーフェスと同様に、破壊的変更が発生する可能性があります。プラグインではテスト済みの Nebula Logger バージョンに固定し、アップグレード後に再検証してください。
プラグインフレームワークの概要
Nebula Logger のプラグインフレームワークでは、次の 2 つの拡張ポイント内で実行する Apex クラスを登録できます。
- トリガー拡張ポイント -
LogEntryEvent__e、Log__c、LogEntry__c、LogEntryTag__c、LoggerScenario__c、LoggerTag__cのトリガーでLoggerSObjectHandlerが実行される際に動作します。ログ作成時に項目を追加したり、データを拡充したり、外部通知を送信したりする場合に使用します。 - バッチ拡張ポイント -
LogBatchPurgerの実行時に動作します。ログを外部システムにアーカイブしたり、カスタムのパージポリシーを適用したり、削除前にパージ対象レコードのメトリクスを出力したりする場合に使用します。
両方の拡張ポイントは LoggerPlugin__mdt レコードによって制御されます。プラグインを追加するには、適切なインターフェース(トリガーとバッチの両方を担当する場合は両方)を実装する Apex クラスを作成し、そのクラスを指定する LoggerPlugin__mdt レコードを作成します。
どちらの拡張ポイントでも、Flow より Apex を強く推奨します。 フレームワークは SObjectHandlerFlowName__c / BatchPurgerFlowName__c を使用した Flow ベースのプラグインも技術的にはサポートしていますが、現在、解決時期が定まっていない既知の問題があります。将来のリリースで完全に非推奨となる可能性もあります。新しいプラグインでは、以下の Apex インターフェースを実装し、LoggerPlugin__mdt レコードの Flow 項目は空欄のままにしてください。
2 つのインターフェース
両方のインターフェースは Nebula Logger - Core パッケージの LoggerPlugin にあります。
LoggerPlugin.Triggerable(トリガー拡張ポイント)
次の 1 つのメソッドを実装します。
void execute(LoggerPlugin__mdt configuration, LoggerTriggerableContext input);
configurationはプラグインを登録したLoggerPlugin__mdtレコードです。プラグイン固有の設定を読み取るために使用します。inputは現在のトリガーコンテキストを記述し、sobjectType、triggerOperationType、triggerNew、triggerNewMap、triggerOldMap、およびレコードごとに旧レコードと新レコードのバージョンを組み合わせたtriggerRecordsリストを公開します(Flow から使いやすいように設定されています)。
LoggerPlugin.Batchable(バッチ拡張ポイント)
Database.Batchable のライフサイクルに対応する次の 3 つのメソッドを実装します。
void start(LoggerPlugin__mdt configuration, LoggerBatchableContext input);
void execute(LoggerPlugin__mdt configuration, LoggerBatchableContext input, List<SObject> scopeRecords);
void finish(LoggerPlugin__mdt configuration, LoggerBatchableContext input);
scopeRecords は、LogBatchPurger が処理しようとしている現在のレコードバッチです。LogBatchPurger はオブジェクト階層を最下位から順にたどり(LogEntryTag__c、次に LogEntry__c、次に Log__c)、親の Log__c.LogRetentionDate__c が期限切れとなっているレコードに絞り込みます。プラグインの動作をオブジェクトごとに変える必要がある場合は、input.sobjectType を確認してください。
LoggerPlugin__mdt の設定
各プラグインには、LoggerPlugin__mdt レコードが1つ必要です。主なフィールドは次のとおりです。
| フィールド | 用途 |
|---|---|
DeveloperName / Label | プラグインを識別します。 |
IsEnabled__c | レコードを削除せずに有効・無効を切り替えます。SubscriberControlled としてマークされているため、インストール済みの組織で管理者が切り替えられます。 |
SObjectHandlerApexClass__c | LoggerPlugin.Triggerable を実装する Apex クラス名です。トリガー拡張ポイントにクラスを登録するには、この値を設定します。 |
SObjectHandlerFlowName__c | Flow ベースのトリガープラグインの Flow API 名です。null のままにしてください。上記の「Apex を優先」の注記を参照してください。 |
SObjectHandlerExecutionOrder__c | 同じハンドラー上の複数プラグインの実行順序を指定する整数です。数値が小さいものから実行されます。同じ値の場合は、開発者名で順序が決まります。 |
BatchPurgerApexClass__c | LoggerPlugin.Batchable を実装する Apex クラス名です。バッチ拡張ポイントにクラスを登録するには、この値を設定します。 |
BatchPurgerFlowName__c | Flow ベースのバッチプラグインの Flow API 名です。null のままにしてください。上記の「Apex を優先」の注記を参照してください。 |
BatchPurgerExecutionOrder__c | 複数のバッチプラグイン間の実行順序です。 |
Description__c / Link__c / VersionNumber__c | 管理者向けに Logger Console に表示されるメタデータです。 |
クラスが実装する内容に応じて、Apex クラスフィールドを組み合わせて設定します。LoggerPlugin.Triggerable の場合は SObjectHandlerApexClass__c、LoggerPlugin.Batchable の場合は BatchPurgerApexClass__c を設定します。両方のインターフェースを実装する場合(LogEntryArchivePlugin など)は、両方のフィールドに同じクラスを指定します。Flow フィールドはnullのままにしてください。
プラグインのフォルダ構成
既存の nebula-logger/plugins/<name>/ 配下のプラグインは、一貫した構成になっています。新しいプラグインを作成するときも、同じ構成にしてください。
nebula-logger/plugins/<name>/
plugin/
classes/ # Apex classes (both implementation and *_Tests.cls test classes)
customMetadata/ # LoggerPlugin.<Name>.md-meta.xml
objects/ # Any plugin-specific custom objects/fields (optional)
permissionsets/ # <Name>PluginAdmin.permissionset-meta.xml (optional)
testSuites/ # <Name>Plugin.testSuite-meta.xml grouping the plugin's test classes
README.md
テストクラスは、テスト対象のコードと同じ plugin/classes/ フォルダに置きます。トップレベルの tests/ フォルダに分けることはありません。Slack プラグインの plugin/slack/ サブフォルダは、共有の core/main メタデータをパッケージ化するための、プラグイン固有の例外です。新しいプラグインでは余分な階層を設けず、すべてを plugin/ の直下に配置してください。
LoggerPlugin.<Name>.md-meta.xml ファイルは登録レコードです。上記のガイダンスに従って、SObjectHandlerApexClass__c および/または BatchPurgerApexClass__c を設定してください。参考にできる既存のプラグインは次のとおりです。
nebula-logger/plugins/slack/- Slack 通知を送信するトリガープラグインです。nebula-logger/plugins/log-retention-rules/- CMDT ルールに基づいてLogRetentionDate__cを設定するトリガープラグインです。nebula-logger/plugins/big-object-archiving/- 1つのクラス(LogEntryArchivePlugin)で両方のインターフェースを実装します。トリガー側でレコードを big object に取り込み、バッチ側でパージ前にアーカイブします。nebula-logger/plugins/async-failure-additions/-FlowExecutionErrorEvent、予期しないバッチ失敗、Queueable のファイナライザーのロギングを追加します。
順序と組み合わせ
- トリガープラグインは、そのオブジェクトに対する組み込みの
LoggerSObjectHandlerロジックの後に実行されます。 - 同じハンドラー上の複数のプラグインは、
SObjectHandlerExecutionOrder__cの順序で実行されます(null は最後にし、その後DeveloperName順)。 - トリガーレコードを変更するプラグイン(タグの追加、項目の設定など)は、通知に拡充済みのデータが渡るように、送信通知を公開するプラグインより先に実行してください。
プラグインのテスト
- 各プラグインには、実装クラスと同じ
plugin/classes/に対応する<PluginClass>_Tests.clsを含めてください。 - プラグインのテストクラスを
plugin/testSuites/の<Name>Plugin.testSuite-meta.xmlに追加してください(パターンについてはLoggerLogEntryArchivePlugin.testSuite-meta.xmlとLoggerLogRetentionRulesPlugin.testSuite-meta.xmlを参照)。このテストスイートはsf apex run test --suite-names <Name>Pluginの呼び出し対象になります。現在、専用のnpm run test:apex:suite:coreスクリプトがあるのはコアパッケージのみです。プラグインのテストスイートは、RunLocalTestsを実行するnpm run test:apexまたはアドホックなsf apex run test --suite-namesの呼び出しを通じて実行されます。 - トリガープラグインでは、実行対象のトリガーレコードを指定して
LoggerTriggerableContextを手動で構築し、execute(configuration, input)を直接呼び出してください。テストで実際のトリガー発火を必要としないでください。 - バッチプラグインでは、
LoggerBatchableContextを構築し、生成したscopeRecordsリストを渡してください。副作用(DML、System.Test.setMockを介したコールアウト、公開イベント)をアサートしてください。
新しいプラグインのチェックリスト
新しいプラグインをリリースする前に、以下を確認してください。
- Apex クラスは
LoggerPlugin.Triggerable/LoggerPlugin.Batchableの少なくとも一方を実装しています。1 つのクラスでトリガーイベントへの対応とパージバッチへの参加の両方が必要な場合は、両方を実装してもかまいません。 LoggerPlugin.<Name>.md-meta.xmlが存在し、IsEnabled__c=true(オプトインの場合はfalse)に設定されており、実装するインターフェースに対応するクラス名項目が設定されています。Triggerableの場合はSObjectHandlerApexClass__c、Batchableの場合はBatchPurgerApexClass__c、両方のインターフェースを実装する場合は両方の項目です。<Name>PluginAdmin.permissionset-meta.xmlで、プラグインが所有するオブジェクトと CMDT へのフルアクセスを許可しています。<PluginClass>_Tests.clsで、正常系、空のスコープ、設定が無効なケースを網羅しています。- プラグインフォルダーの
README.mdに、インストール手順と前提条件を記載しています。 sfdx-project.jsonにプラグインのpackageDirectoriesエントリーがあり、独立したアンロックパッケージとしてビルドおよびインストールできるようになっています。
関連スキル
- nebula-logger-console - コンソールの
LoggerPlugin__mdtリストビューで、管理者がプラグインのオン/オフを切り替えます。 - nebula-logger-purging-and-retention -
LoggerPlugin.Batchableプラグインを組み込む場所です。