を呼び出す Akka Actor がありますMyObject.foo()
。MyObject
俳優ではありません。ログインを設定するにはどうすればよいですか? Actor の場合は、ActorLogging を mixin するだけなので簡単です。MyObject では、context.system にアクセスできません。akka.event.Logging
AkkaSystem()を使用して作成し、LogSource を暗黙的に作成しますか?
6 に答える
実際、私はAkkaロギングをslf4jにリダイレクトし、このAPIをすべての無関係なクラスで直接使用します。まず、これを構成に追加します。
akka {
event-handlers = ["akka.event.slf4j.Slf4jEventHandler"]
loglevel = "DEBUG"
}
次に、 SLF4Jの実装を選択します。ログバックをお勧めします。あなたの俳優では、ActorLogging
特性を使い続けます。他のクラスでは、SLF4J APIに依存するだけで、さらに良いことに、 SLF4Jの周りのslf4sファサードを試してみてください。
ヒント:ログバックで次のログパターンを試してください。
<pattern>%d{HH:mm:ss.SSS} | %-5level | %thread | %X{akkaSource} | %logger{1} | %m%n%rEx</pattern>
%X{akkaSource}
利用可能な場合、アクターパスを出力します(標準のロギングと同様)。
前述したように、アクター システム内でアクター以外のログを記録するためのオプションが必要です。作業のためにロギングをルーティングする方法を決定するのに役立つ一連のヒューリスティックを提供しようとしています。
- アクター コードと非アクター コードの両方でロガー (log4j 1.x、logback、log4j 2.x) を直接使用できます。
- これにより、コードがロガーの実装に緊密に結合されます。これはあなたのコードであれば問題ありませんが、ライブラリを構築している場合や作業をオープン ソース化する場合は問題ありません。
- これを行うと、アクター システムから何のメリットも得られません。ロガーの設定方法によっては、ロギング呼び出しがブロッキング呼び出しになる可能性があるため、パフォーマンスやバック プレッシャーの制御が重要な問題である場合は、これは嫌われます。
- アクター コードは (消費可能なサービスと共に) 多くの異なるスレッドで動作する可能性があるため、スレッドローカル MDC (マップされた診断コンテキスト) の使用などの従来のロギング アクティビティによって、奇妙な競合状態や、メッセージからのログ出力によるコンテキストの切り替えが発生する可能性があります。アクターからアクターへと渡ります。メッセージを送信する前に MDC をメッセージにスワップするなどのアクティビティは、アクター コードと非アクター コードの間のコンテキストを保持するために必要になる場合があります。
- デッド レターや監視などの ActorSystem イベントをキャプチャするには、ロギング アダプターを作成し、application.conf で指定する必要がある場合があります。これらは非常に簡単です。
- SLF4J ファサードは、アクター ロギングと非アクター ロギングの両方に使用できます。
- ロガー impl に結合されなくなり、サービスが akka に結合されなくなりました。これは、移植性に最適なオプションです。
- ログ フレームワークからブロック動作を継承する場合があります。
- MDC の管理が必要になる場合があります
- ActorSystem イベントをキャプチャするには、application.conf で「akka.event.slf4j.Slf4jLogger」を指定する必要があります。
- 選択したロガーに slf4j ログ イベントをルーティングするには、クラスパスに slf4j プロバイダー jar を含める必要があります。
- アクター コードと非アクター コードの両方で、ファサードとして Akka の Logging を使用できます。
- ロガーの impl または slf4j に接続されていませんが、akka のバージョンに接続されています。とにかく、これはおそらくシステムの要件ですが、ライブラリの場合、移植性が低下する可能性があります。
- ロガーの「バス」として機能するには、アクター システムを通過する必要があります。稼働中のアクター システムへの密結合は、移植性をさらに低下させます。(アプリ内では、通常、暗黙的またはグローバルな ActorSystem を使用して小さな LoggingViaActorSystem トレイトを構築します。これにより、コード内でこれを簡単に処理できますが、依存関係を越えて処理することはできません)。
- ロガーがサポートしていない場合でも、ノンブロッキングの非同期ロギングが保証されます。ロギングの因果的一貫性は、単一のコンシューマー メールボックスの使用による可能性があります。ただし、メモリの安全性とバック プレッシャはそうではありません (Akka のログ記録は無制限のメールボックスを使用していると思います) --
- 作業がアクターからアクターに渡されるときに独自の MDC を管理する複雑さを回避するためのDiagnosticLoggingAdapterの使用などのオプションがあります。アクター以外のコードがこれらの MDC を変更しても、一貫性を維持する必要があります。
- メモリ不足のクラッシュ中はロギングが利用できない可能性が高く、デフォルトのディスパッチャーでのスレッド不足の影響を受けやすい
- 標準出力にログインすることに興味がない限り、選択したロガーを application.conf で指定する必要があります。
要件を満たすために、必要に応じて上記の動作を自由に組み合わせてください。たとえば、ライブラリ用に SLF4J にバインドし、その他すべてに Akka ロギングを使用することを選択できます。ブロッキング ロギングと非ブロッキング ロギングを混在させると、競合状態が発生する可能性があることに注意してください。原因 (アクターを介して非同期でログに記録される) は、その結果 (同期が直接ログに記録される) の後に記録されます。
ここでは、DI コンストラクター インジェクション (Guice) を使用して、中央のログ システムを単純に渡すことにしました。また、定期的にログを記録するクラス (非同期性が重要な場合) では、注入された ActorSystem を取得して、
this.log = akka.event.Logging.getLogger(actorSystem, this);
クラスコンストラクターで。
最新 (現在のバージョン 2.6.9) のログ ドキュメントによると、取得した Logger を使用することorg.slf4j.LoggerFactory
はまったく問題なく、実際にアクターの外部でログを記録する方法として推奨されています。以下、正確な文言をコピーします。
org.slf4j.LoggerFactory を介して取得したロガーを使用しても問題ありませんが、ログ イベントには akkaSource MDC 値が含まれません。これは、 Future コールバックからのロギングを含め、アクターの外部でロギングする場合に推奨される方法です。
また、例に基づいたスニペットを以下に提供します
val log = LoggerFactory.getLogger("com.mypackage.MyObject")
Future {
// do something
"result"
}.onComplete {
case Success(result) => log.info("Success!: {}", result)
case Failure(exc) => log.error("Failure!", exc)
}
ロギングによるパフォーマンスの低下を最小限に抑えるために、SLF4J バックエンドの非同期アペンダーを構成できます。Logback は、推奨されるロギング バックエンドです。
dependencies {
compile group: 'ch.qos.logback', name: 'logback-classic', version: '1.2.3'
}
実動用の logback.xml の構成の開始点:
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>myapp.log</file>
<immediateFlush>false</immediateFlush>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>myapp_%d{yyyy-MM-dd}.log</fileNamePattern>
</rollingPolicy>
<encoder>
<pattern>[%date{ISO8601}] [%level] [%logger] [%marker] [%thread] - %msg MDC: {%mdc}%n</pattern>
</encoder>
</appender>
<appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender">
<queueSize>8192</queueSize>
<neverBlock>true</neverBlock>
<appender-ref ref="FILE" />
</appender>
<root level="INFO">
<appender-ref ref="ASYNC"/>
</root>
ロギングは一般的に IO とロックを意味し、同期的に実行された場合、コードの操作が遅くなる可能性があります。
上記の構成は、AKKA ロギング ドキュメントで提供されているものです。ドキュメントは詳細を提供し、ここで見つけることができます