2009-12-09 49 views
7

Tôi muốn triển khai một lớp đơn giản để ghi nhật ký từ nhiều luồng. Ý tưởng có, rằng mỗi đối tượng muốn đăng nhập công cụ, nhận được một đối tượng ostream rằng nó có thể viết tin nhắn để sử dụng các toán tử thông thường. Hành vi mong muốn là, các tin nhắn được thêm vào nhật ký khi luồng được xả. Bằng cách này, tin nhắn sẽ không bị gián đoạn bởi các tin nhắn từ các chủ đề khác. Tôi muốn tránh sử dụng một chuỗi tạm thời để lưu trữ tin nhắn, vì điều đó sẽ làm cho hầu hết các thông điệp ít nhất là twoliners. Như tôi đã thấy, cách tiêu chuẩn để đạt được điều này là triển khai trình tạo luồng dữ liệu của riêng tôi, nhưng điều này có vẻ rất cồng kềnh và dễ bị lỗi. Có cách nào đơn giản hơn để thực hiện việc này không? Nếu không, bạn có biết một bài viết/hướng dẫn/bài viết hay về streambufs tùy chỉnh không?Ghi nhật ký an toàn

Cảm ơn trước,

Space_C0wbo0y

UPDATE:

Vì nó dường như làm việc tôi đã thêm câu trả lời của riêng tôi.

+0

Có vẻ như một giải pháp tốt! Có lẽ thêm nó như là câu trả lời của riêng bạn? –

Trả lời

1

Vì vậy, tôi đã xem xét Boost.IOstreams và đây là những gì tôi đã đưa ra:

class TestSink : public boost::iostreams::sink { 
public: 
    std::streamsize write(const char * s, std::streamsize n) { 
     std::string message(s, n); 
      /* This would add a message to the log instead of cout. 
       The log implementation is threadsafe. */ 
     std::cout << message << std::endl; 
     return n; 
    } 
}; 

TestSink thể được sử dụng để tạo ra một dòng-đệm (xem stream_buffer-template). Mỗi chuỗi sẽ nhận được ví dụ riêng của nó là TestSink, nhưng tất cả TestSinks sẽ ghi vào cùng một nhật ký. TestSink được sử dụng như sau:

TestSink sink; 
boost::iostreams::stream_buffer<TestSink> testbuf(sink, 50000); 
std::ostream out(&testbuf); 

for (int i = 0; i < 10000; i++) 
    out << "test" << i; 

out << std::endl; 

Thực tế quan trọng ở đây là, rằng TestSink.write chỉ gọi khi dòng là đỏ ửng (std::endl hoặc std::flush), hoặc khi bộ đệm bên trong của stream_buffer dụ là đầy đủ (bộ đệm mặc định kích thước không thể chứa 40000 ký tự, vì vậy tôi initalize nó đến 50000). Trong chương trình này, TestSink.write được gọi chính xác một lần (đầu ra quá dài để đăng ở đây). Bằng cách này tôi có thể viết logmessage bằng cách sử dụng bình thường định dạng dòng-IO mà không có bất kỳ biến tạm thời và chắc chắn rằng thông điệp được đăng vào nhật ký trong một mảnh khi tôi tuôn ra dòng.

Tôi sẽ để câu hỏi mở một ngày khác, trong trường hợp có các đề xuất/vấn đề khác nhau mà tôi chưa xem xét.

5

Hãy xem log4cpp; họ có hỗ trợ đa luồng. Nó có thể tiết kiệm thời gian của bạn.

+0

Cảm ơn bạn đã trả lời. Tuy nhiên, do hạn chế môi trường làm việc của tôi, tôi không thể giới thiệu một thư viện mới. Ngoài ra, hầu hết các thư viện đăng nhập hiện có đều quá nặng so với mục đích của tôi. –

+0

Nếu tìm kiếm giấy phép tự do hơn, hãy xem Log4cxx by Apache. http://logging.apache.org/log4cxx/index.html –

0

Re. phản ứng của riêng bạn. Nếu bạn đang sử dụng này cho lỗi đăng nhập và bạn chương trình bị treo trước khi xả luồng của bạn sau đó bạn đăng nhập là một chút vô dụng phải không?

+1

Tôi đoán đó sẽ là một vấn đề với bất kỳ phương thức ghi nhật ký nào. –

+0

Ngoại trừ các hệ thống khai thác gỗ như ETW có trợ giúp bên ngoài. – VoidStar

1

Bạn cho rằng log4cpp quá nặng và bạn tiếp cận với Boost.IOStream thay thế? Huh?

Bạn có thể xem xét logog. Đó là chủ đề an toàn cho POSIX, Win32 và Win64.

+0

Nếu tăng cường đã có trong bộ thư viện của mình, thì nó không phải là trọng lượng nặng.Nếu không, hoàn toàn đồng ý với bạn. – John

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