2012-04-14 161 views
42

我有一個Akka Actor來調用MyObject.foo()。 MyObject不是演員。如何設置登錄?與演員很簡單,因爲我可以混入ActorLogging。在MyObject中,我無法訪問context.system。我是否使用AkkaSystem()創建akka.event.Logging,然後LogSource是隱式的?Akka Logging outside Actor

+0

您已閱讀過? :http://doc.akka.io/docs/akka/2.0/scala/logging.html – 2012-04-14 23:18:43

+6

@ViktorKlang是的。但它似乎沒有解決我的問題,也沒有描述爲什麼Akka事件記錄器是需要的(而不是直接在Actor中使用SLF4J)。 – Bradford 2012-04-15 02:39:12

+1

由於日誌記錄是通過參與者完成的,因此可以使任何日誌記錄後端異步。 – 2012-04-15 17:43:52

回答

22

其實我阿卡記錄重定向到並直接在所有不相關的類使用這個API。首先添加到您的配置:

akka { 
    event-handlers = ["akka.event.slf4j.Slf4jEventHandler"] 
    loglevel = "DEBUG" 
} 

然後選擇一些SLF4J實施,我建議。在你的演員中繼續使用ActorLogging特質。在其他課程中,只需依賴SLF4J API - 甚至更好 - 在SLF4J周圍嘗試使用slf4s外觀。

提示:請嘗試以下記錄模式中的logback:

<pattern>%d{HH:mm:ss.SSS} | %-5level | %thread | %X{akkaSource} | %logger{1} | %m%n%rEx</pattern> 

%X{akkaSource}將打印演員路徑時可用(就像標準的日誌記錄)。

+0

謝謝。我不完全確定爲什麼ActorLogging存在,但是因爲它的確如此,我的演員調用的方法是直接使用SLF4J API而不是使用Akka的日誌記錄事件系統嗎?有什麼危險?或者,我可以創建一個日誌記錄參與者,並在那裏發送日誌消息。這裏首選什麼? – Bradford 2012-04-14 22:19:04

+1

但是如果你直接使用SLF4J的工廠,你不會得到異步日誌記錄,對吧?我使用髒靜態來訪問System對象atm:/ – 2012-04-23 18:11:39

+2

@AntonyStubbs:不,如果您想從異步日誌記錄中受益,則必須向某個參與者發送消息,然後使用該參與者來記錄消息。 。 – 2012-04-23 19:12:11

8

我現在已經定居在經過簡單的在我的中央登記系統,通過DI構造函數注入(吉斯)。而在我的課那些經常登錄(其中異步是非常重要的),我拿注入ActorSystem並調用

this.log = akka.event.Logging.getLogger(actorSystem, this); 
在類的構造函數

+3

另一個選項,如果您不希望增長對象來保存這樣的引用,您可能更喜歡將另一個參數列表'(implicit log:LoggingAdapter)'添加到需要執行日誌記錄的方法中。 – AmigoNico 2013-10-12 06:19:38

20

使用阿卡2.2.1,我可以把我的應用它來獲取登錄演員之外:

import akka.event.Logging 
val system = ActorSystem("HelloSystem", ConfigFactory.load.getConfig("akka")) 
val log = Logging.getLogger(system, this) 
log.info("Hi!") 

這似乎是一個統一的應用程序的日誌記錄簡單的解決方案。

+0

這是讓我走的最簡單的方法 - 謝謝! – akauppi 2014-07-29 09:35:11

+6

這個答案並不能解決實際問題。你創建一個完整的ActorSystem只是爲了在一個類中做一些日誌記錄。如果你需要它,你會創建另一個ActorSystem?不妨通過你的第一個創建的ActorSystem的參考。 – 2015-07-08 18:38:02

6

正如已經提到的,你寵壞的演員系統內非演員記錄選項。我將嘗試提供一套啓發式方法來幫助您確定如何爲工作路由記錄。

  1. 您可以在演員代碼和非演員代碼中直接使用記錄器(log4j 1.x,logback,log4j 2.x)。
    • 這種緊耦合代碼到記錄器的實現。這是好的,如果它是你的代碼,不要在其他地方使用,但如果你正在建立一個圖書館或打算開源你的工作,那就不好。
    • 如果你這樣做,你不會從演員系統中獲益。記錄呼叫可能會成爲阻塞呼叫,具體取決於您如何設置記錄器,因此無論性能還是背壓控制都是重要問題,這種情況都會受到影響。
    • 因爲演員碼(與服務一起就可以消耗)可以在許多不同的線程操作,一些傳統的伐木活動,如使用一個ThreadLocal MDC(映射診斷上下文)的會導致奇怪的比賽條件和背景原木輸出swtiching從演員傳遞給演員的消息。諸如在發送消息之前將MDCs交換到消息之類的活動對於保存參與者和非參與者代碼之間的上下文可能是必要的。
    • 要捕捉ActorSystem事件,如一紙空文,監督,你可能需要編寫一個日誌適配器和您的application.conf指定。這些非常簡單。
  2. 您可以將SLF4J外觀用於actor和non-actor日誌。
    • 您不再與記錄器impl耦合,而且您的服務不再耦合到akka。這是便攜性的最佳選擇。
    • 您可能會從日誌框架繼承阻止行爲。
    • 您可能需要管理的MDC
    • 爲了捕捉你需要在你的application.conf指定「akka.event.slf4j.Slf4jLogger」 ActorSystem事件
    • 你需要對包括SLF4J提供商罐子類路徑路由SLF4J日誌事件到您選擇的記錄
  3. 您可以使用阿卡的記錄爲您​​的門面在這兩個演員與非演員代碼
    • 您沒有連接到記錄器IMPL OR給... lf4j,但你加入了akka版本。無論如何,這可能是您的系統的一個要求,但對於圖書館來說,它可能會降低可移植性。
    • 你必須繞過演員系統來充當記錄器的「公交車」。緊密耦合到工作角色系統會進一步降低可移植性。 (在應用程序中,我通常會使用隱式或全局ActorSystem構建一個LoggingViaActorSystem特徵,這使得在代碼中處理此操作更容易,但不會跨越依賴關係)。
    • 即使您的記錄器不支持它們,也可以保證非阻塞異步記錄。記錄的因果一致性可能是由於使用單個消費者郵箱。但是,內存安全和背壓不是(我相信Akka日誌記錄使用無限制的郵箱) -
    • 有一些選項,如使用 DiagnosticLoggingAdapter避免管理自己的MDC的複雜性,因爲工作從actor到actor傳遞。即使非行動者代碼改變這些MDC,也應保持一致性。
    • 記錄在內存不足崩潰期間可能不可用,並且對默認調度程序中的線程飢餓敏感
    • 您需要在application.conf中指定您選擇的記錄器,除非您有興趣在記錄到標準輸出

歡迎你混搭所必需的滿足您的要求上述行爲。例如,您可以選擇將庫綁定到SLF4J,並使用Akka日誌記錄來查找其他所有內容。只需注意混合阻塞和非阻塞日誌記錄可能會導致競爭條件,其原因(通過參與者記錄的異步)會在它們的影響(直接記錄同步)之後被記錄。