2017-01-24 17 views
0

私は、ロギングの問題のために、最良の、またはより良い設計上の決定を探しています。 私はバックエンドサービスのためにクラスタでAkkaアクターを使用しており、HTTPリクエストを受け入れるにはフロントエンドでPlayしています。 私の質問は、最初のUUIDを生成してコンテキストに入れることによって、アプリケーションログ全体を同じHTTPリクエストに識別させるという古い質問から拡張されました。同じ「要求」のアクターログをグループ化/識別する

我々のデータの流れの一例は次のようになります。

"HTTPリクエスト/システムA" - > "Actor1 /クラスタB" - > "ACTOR2 /クラスタC" - >「システムAと完全に返信します要求」

これは、プロセスに少なくとも3つの別々のシステムが含まれていることを意味します。 私のすべてのログはLogstashに送られます。 システムAからの要求の開始からUUIDを生成することができます。 しかし、すべてのサブシステムにUUIDを/ piggy-backedで渡すことができます。これらはすべて、Protobufシリアル化を使用して通信し、ジョブを処理します同じhttp要求に属しています。

私はすべてのメッセージにidフィールドを追加することができますが、これは非常に醜いです。

ビジネスロジックの処理にあまりノイズをかけることなく、他のすべての呼び出し元のAkkaシステムに情報を伝達するためのよりよい方法があるかどうかは疑問です。

case class MessageWithUuid(message: Any, uuid: UUID) 

その後、中にあなたのreceiveあなたがそれをアンラップし、ロギング用uuid維持する必要があります:

+0

私が知っているのは "醜い"オプションだけです。 – Rumoku

+0

あなたは、httprequestに基づいて決定的なID生成を行うことができます。このようにすれば、すべてのシステムは単にログするときに同じIDを生成しますか? – C4stor

+0

@ C4storどうすればいいのかよく分かりません。実際には、システムAのエントリポイントを除いて、他のすべてのアクターシステムはprotobufシリアライゼーションを使用して受信します。私はそれについてはっきりしていなかったと思います。 – lunaspeed

答えて

1

あなたはUUIDを容器にあなたの元のメッセージをラップすることができます

var uuid: Option[UUID] = 
def receive: Receive = { 
    case MessageWithUuid(message, uuid) => 
    this.uuid = Some(uuid) 
    //TODO: put UUID to MDC logging context 
    receive(message) 
    //TODO: remove UUID from MDC 
    this.uuid = None 
    case ... => 
} 

をそして、あなたが送ったときにメッセージを別のアクタに送信するには、UUIDでラップする必要があります。

def send(actor: ActorRef, message: Any) = actor ! MessageWithUuid(message, uuid.get) 
+0

これは "id everywhere"と似ていますが、確かに良い解決策です。しかし、私はProtobufのシリアライゼーションを使用していると言及することを忘れて、私のポストを編集しました。このポストは、このようなアプローチのために厄介なようです。 – lunaspeed

関連する問題