2012-04-14 48 views
42

Tôi có một diễn viên Akka thực hiện cuộc gọi đến MyObject.foo(). MyObject không phải là diễn viên. Làm cách nào để thiết lập Ghi nhật ký trong đó? Với một diễn viên nó đơn giản, bởi vì tôi chỉ có thể mixin ActorLogging. Trong MyObject, tôi không có quyền truy cập vào context.system. Tôi có tạo ra một akka.event.Logging với AkkaSystem() và sau đó những gì cho LogSource tiềm ẩn?Akka Đăng nhập bên ngoài diễn viên

+0

Bạn đã đọc sách này chưa? : http://doc.akka.io/docs/akka/2.0/scala/logging.html –

+6

@ViktorKlang yep. Nó dường như không giải quyết được câu hỏi của tôi, và nó cũng không mô tả lý do tại sao bộ ghi sự kiện Akka là cần thiết (trái ngược với việc chỉ sử dụng SLF4J trực tiếp trong diễn viên). – Bradford

+1

Bởi vì bạn có thể thực hiện bất kỳ phụ trợ ghi nhật ký nào không đồng bộ do việc ghi nhật ký được thực hiện thông qua một tác nhân. –

Trả lời

22

Thực ra tôi sẽ chuyển hướng đăng nhập Akka tới và sử dụng API này trực tiếp trong tất cả các lớp không liên quan. Trước tiên, hãy thêm cấu hình này vào cấu hình của bạn:

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

Sau đó chọn một số triển khai SLF4J, tôi đề xuất . Trong diễn viên của bạn tiếp tục sử dụng tính năng ActorLogging. Trong các lớp khác chỉ đơn giản là dựa vào API SLF4J - hoặc thậm chí tốt hơn - hãy thử slf4s mặt tiền xung quanh SLF4J.

Mẹo: thử các mô hình khai thác gỗ sau trong Logback:

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

Các %X{akkaSource} sẽ in con đường diễn viên khi có sẵn (giống như khai thác gỗ tiêu chuẩn).

+0

Cảm ơn.Tôi không hoàn toàn chắc chắn tại sao ActorLogging tồn tại, nhưng vì nó có vấn đề gì, phương pháp mà diễn viên của tôi gọi là sẽ sử dụng API SLF4J trực tiếp thay vì sử dụng hệ thống ghi nhật ký sự kiện của Akka? Có nguy hiểm gì không? Ngoài ra, tôi có thể tạo một diễn viên đăng nhập và chỉ cần gửi thông điệp tường trình ở đó. Có gì ưa thích ở đây? – Bradford

+1

Nhưng nếu bạn sử dụng trực tiếp nhà máy của SLF4J, bạn không nhận được đăng nhập Async, phải không? Tôi đang sử dụng số liệu thống kê bẩn để truy cập vào đối tượng Hệ thống atm:/ –

+2

@AntonyStubbs: không, nếu bạn muốn hưởng lợi từ việc ghi nhật ký không đồng bộ, bạn sẽ phải gửi thư tới một số diễn viên - và sử dụng diễn viên đó để đăng nhập thư. –

8

Bây giờ tôi đã định cư chỉ đơn giản là chuyển hệ thống ghi nhật ký trung tâm của tôi xung quanh thông qua tiêm DI constructor (Guice). Và trong các lớp học của tôi thường xuyên ghi nhật ký (nơi tính đồng bộ là quan trọng), tôi lấy ActorSystem được tiêm và gọi số

this.log = akka.event.Logging.getLogger(actorSystem, this); 

trong hàm tạo lớp.

+3

Một tùy chọn khác mà bạn có thể thích hơn đối với các trường hợp bạn không muốn phát triển đối tượng để giữ tham chiếu đó là thêm một danh sách tham số thứ hai '(implicit log: LoggingAdapter)' vào các phương thức cần phải ghi nhật ký. – AmigoNico

20

Sử dụng Akka 2.2.1, tôi đã có thể đưa điều này vào App của tôi để có được đăng nhập bên ngoài của một diễn viên:

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

Điều này có vẻ giống như một giải pháp đơn giản cho thống nhất khai thác gỗ của ứng dụng.

+0

Đây là cách dễ nhất để tôi đi - cảm ơn! – akauppi

+6

Câu trả lời này không giải quyết được vấn đề thực tế. Bạn tạo toàn bộ ActorSystem chỉ để thực hiện một số việc đăng nhập vào một lớp. Nếu bạn cần nó ở một nơi khác thì bạn sẽ tạo một ActorSystem khác? Cũng có thể vượt qua tham chiếu của ActorSystem được tạo đầu tiên của bạn xung quanh. –

6

Như đã được đề cập, bạn đã tha hồ lựa chọn đăng nhập không diễn viên trong hệ thống diễn viên. Tôi sẽ cố gắng cung cấp một tập hợp các chẩn đoán để giúp bạn xác định cách bạn nên định tuyến khai thác gỗ cho công việc của mình.

  1. Bạn có thể sử dụng trình ghi nhật ký (log4j 1.x, logback, log4j 2.x) trực tiếp trong cả mã tác nhân và không phải diễn viên.
    • Việc này kết hợp chặt chẽ mã của bạn với việc triển khai trình ghi nhật ký. Điều này là tốt nếu đó là mã của bạn, không được sử dụng ở nơi khác, nhưng không tốt nếu bạn đang xây dựng một thư viện hoặc có ý định mở nguồn công việc của bạn.
    • Nếu bạn làm điều này, bạn sẽ không được hưởng lợi ích từ hệ thống diễn viên. Việc ghi nhật ký cuộc gọi có thể trở thành chặn cuộc gọi, tùy thuộc vào cách bạn đã thiết lập bộ ghi nhật ký của mình và do đó điều này không được chấp nhận khi có hiệu suất hoặc kiểm soát áp lực ngược là những mối quan tâm quan trọng.
    • Vì mã diễn viên (cùng với các dịch vụ có thể tiêu thụ) có thể hoạt động trên nhiều luồng khác nhau, một số hoạt động ghi nhật ký truyền thống như sử dụng MDC theo chủ đề (Ngữ cảnh chẩn đoán được ánh xạ) có thể dẫn đến điều kiện cuộc đua kỳ lạ và bối cảnh từ các thư chuyển từ diễn viên đến diễn viên. Các hoạt động như trao đổi các MDC vào các tin nhắn trước khi gửi chúng có thể trở nên cần thiết để bảo vệ bối cảnh giữa mã tác nhân và không phải là diễn viên.
    • Để nắm bắt các sự kiện ActorSystem như chữ cái chết và giám sát, bạn có thể cần phải viết bộ chuyển đổi ghi nhật ký và chỉ định nó trong tệp tin application.conf của bạn. Đây là khá đơn giản.
  2. Bạn có thể sử dụng mặt tiền SLF4J cho cả việc ghi nhật ký diễn viên và không phải diễn viên.
    • Bạn không còn được kết hợp với trình ghi nhật ký và dịch vụ của bạn không được kết hợp với akka. Đây là tùy chọn tốt nhất cho tính di động.
    • Bạn có thể kế thừa hành vi chặn từ khung đăng nhập của mình.
    • Bạn có thể phải quản lý MDCs
    • Để chụp ActorSystem sự kiện mà bạn sẽ cần phải xác định "akka.event.slf4j.Slf4jLogger" trong application.conf bạn
    • Bạn sẽ cần phải bao gồm một lọ cung cấp slf4j trên classpath để định tuyến slf4j sự kiện đăng nhập để logger bạn chọn
  3. bạn có thể sử dụng Logging Akka như mặt tiền của bạn trong cả hai diễn viên và phi diễn viên đang
    • You are not cùng với một impl logger HOẶC để s lf4j, nhưng bạn đang kết hợp với một phiên bản của akka. Đây có lẽ là một yêu cầu của hệ thống của bạn anyway, nhưng đối với các thư viện nó có thể làm giảm tính di động.
    • Bạn phải vượt qua xung quanh một hệ thống diễn viên để hoạt động như "xe buýt" cho người ghi nhật ký. Khớp nối chặt chẽ với hệ thống tác nhân làm việc giảm tính di động hơn nữa. (Trong một ứng dụng, tôi thường xây dựng một chút đặc điểm LoggingViaActorSystem với một hệ thống ActorSystem ngầm định hoặc toàn cục, giúp dễ dàng giải quyết vấn đề này bằng mã nhưng không phụ thuộc vào các phụ thuộc).
    • Ghi nhật ký không đồng bộ không chặn được đảm bảo, ngay cả khi trình ghi nhật ký của bạn không hỗ trợ chúng. Tính nhất quán của việc ghi nhật ký có thể do việc sử dụng một hộp thư người tiêu dùng duy nhất. Tuy nhiên, an toàn bộ nhớ và áp suất ngược không phải là (tôi tin rằng nhật ký Akka sử dụng hộp thư không bị chặn) -
    • Có các tùy chọn như sử dụng DiagnosticLoggingAdapter để tránh sự phức tạp của việc quản lý MDC của riêng bạn khi công việc chuyển từ diễn viên này sang diễn viên khác. Tính nhất quán phải được bảo toàn ngay cả khi mã không diễn viên làm thay đổi các MDC này.
    • Tính năng ghi nhật ký không có khả năng xảy ra trong khi xảy ra sự cố ngoài bộ nhớ và nhạy cảm với nạn đói trên trình điều phối mặc định
    • Bạn cần chỉ định trình ghi nhật ký đã chọn trong application.conf trừ khi bạn quan tâm trong khai thác gỗ để chuẩn ra

bạn đang chào đón để trộn và kết hợp các hành vi nêu trên nếu cần thiết để đáp ứng yêu cầu của bạn. Ví dụ, bạn có thể chọn liên kết với SLF4J cho các thư viện và sử dụng ghi nhật ký Akka cho mọi thứ khác. Chỉ cần lưu ý rằng việc kết hợp chặn và không chặn có thể gây ra các điều kiện chủng tộc nơi nguyên nhân (đăng nhập không đồng bộ thông qua một diễn viên) được ghi lại sau khi các hiệu ứng của chúng (ghi nhật ký đồng bộ trực tiếp).

Các vấn đề liên quan