2011-11-15 7 views
5

Nhiệm vụ của tôi là tạo một lớp sẽ thu thập hoạt động của người dùng xung quanh một số ứng dụng.Thực hiện ghi nhật ký an toàn theo chủ đề

Giả sử tôi có một lớp TLogging và đối tượng chung được gọi là Logging.

Hoạt động của người dùng (màn hình mở, vv ...) phải được thu thập trong bộ nhớ (có thể được đưa vào danh sách (chuỗi) TLogging) và được lưu vào tệp nhật ký sau một khoảng thời gian (mỗi 10 phút) hoặc khi ứng dụng đã đóng.

Điều quan trọng nhất là ghi nhật ký phải ở "chế độ im lặng", nó không được ảnh hưởng đến quy trình làm việc của người dùng theo bất kỳ cách nào: không có màn hình treo, không có ngoại lệ.

Vui lòng cho tôi hướng dẫn cho tác vụ này.

+2

Bạn có tất cả những tính năng (và cũng có thể các tính năng bổ sung, như truy tìm ngoại lệ, phương pháp lập hồ sơ, thread-an toàn hoặc một mỗi tùy chọn -nhập nhật ký có thể thú vị) trong [lớp TSynLog' mã nguồn mở của chúng tôi] (http://blog.synopse.info/post/2011/04/14/Enhanced-logging-in-SynCommons). Đối với Delphi 5 lên đến XE2. Bao gồm trình xem nhật ký và cấp độ dựa trên tập hợp (không phải một cấp độ toàn cầu, nhưng là một tập hợp các cấp tùy chỉnh). –

+2

@Arnaud Đó không phải là câu trả lời sao? – NGLN

+0

Xem thêm: [Ghi nhật ký và đồng bộ hóa] (http://stackoverflow.com/questions/659094), [Thư viện ghi nhật ký nào tốt hơn?] (Http://stackoverflow.com/questions/72983) và tất cả các quá khứ khác [Delphi đăng nhập] (http://stackoverflow.com/search?q=%5Bdelphi%5D+logging) có liên quan Q & A. – NGLN

Trả lời

14

Đây là một câu hỏi rất rộng chạm vào một số khu vực. Một vài gợi ý:

  • Ít nhất hãy xem xét khung khai thác đã thiết lập cho điều này. Phiên bản Delphi mới hơn có kèm theo CodeSite. SmartInspect là một giải pháp thay thế khác.

  • Sử dụng đồng bộ hóa nguyên thủy để làm cho lớp học của bạn thread-safe: TCriticalSection, TMREWSync

  • Đảm bảo rằng bạn hiểu những vấn đề liên quan đến việc xử lý đa luồng và đồng bộ hóa trước khi cố gắng viết một khung đăng nhập thread-safe. Một khởi đầu tốt là hướng dẫn của Martin Harvey Multithreading - The Delphi Way.

  • Sử dụng chuỗi nền để xóa nội dung nhật ký thành đĩa theo khoảng thời gian đều đặn hoặc nếu đủ dữ liệu đã được lưu vào bộ đệm.

  • Đặt câu hỏi cụ thể hơn tại đây về SO nếu bạn gặp phải các sự cố cụ thể.

3

Sử dụng OmniThreadLibrary và giả định rằng đối tượng Ghi nhật ký đơn giản, điều này thực sự đơn giản. Tôi cũng sẽ giới hạn số lượng thư tối đa chờ đợi để được viết để hàng đợi nội bộ không thể sử dụng quá nhiều bộ nhớ.

const 
    CMaxMsgCount = 1000; 
    CMaxLogTimeout_ms = 10{min}*60{sec/min}*1000{ms/sec}; 

type 
    TLogging = class 
    strict private 
    FLogMsgCount: IOmniResourceCount; 
    FLogQueue: IOmniBlockingCollection; 
    FWriter: IOmniTaskControl; 
    strict protected 
    procedure Logger(const task: IOmniTask); 
    public 
    constructor Create; 
    destructor Destroy; 
    procedure Log(const msg: string); 
    end; 

var 
    Logging: TLogging; 

constructor TLogging.Create; 
begin 
    FLogMsgCount := CreateResourceCount(CMaxMsgCount); 
    FLogQueue := TOmniBlockingCollection.Create; 
    FWriter := CreateTask(Logger, 'Logger').Run; 
end; 

destructor TLogging.Destroy; 
begin 
    FWriter.Terminate; 
end; 

procedure TLogging.Log(const msg: string); 
begin 
    FLogQueue.Add(msg); 
    FLogMsgCount.Allocate; 
end; 

procedure TLogging.Logger(const task: IOmniTask); 

    procedure Flush; 
    var 
    logData: TOmniValue; 
    begin 
    // open file, possibly with retry 
    while FLogQueue.TryTake(logData) do begin 
     FLogMsgCount.Release; 
     // write logData.AsString 
    end; 
    // close file 
    end; 

begin 
    while DSiWaitForTwoObjects(task.TerminateEvent, FLogMsgCount.Handle, false, CMaxLogTimeout_ms) <> WAIT_OBJECT_0 do 
    Flush; 
    Flush; 
end; 

(Disclaimer: "Nó biên dịch trên máy tính của tôi", nếu không chưa được kiểm tra.)