Tôi không biết cách làm điều đó rất dễ dàng. Có nói rằng, tất cả các ví dụ bạn cung cấp có sẵn (hoặc khá dễ dàng có sẵn với một số mã tùy chỉnh) để được thêm vào mỗi thông điệp tường trình. Tức là, mỗi thông điệp đã đăng nhập có thể được gắn thẻ với tên thực thi, phiên bản tệp, ngày phát hành, id người dùng cửa sổ, v.v. qua Bố cục và Trình sắp xếp Layout.
Điều này rõ ràng không giống như việc tạo tiêu đề ở đầu tệp nhật ký, vì vậy nó có thể không hữu ích cho bạn.
Mặt khác, bạn có thể sử dụng kỹ thuật được đề cập trong câu trả lời của Pat in this post để liên kết nhiều trình kết xuất bố cục với cùng một mục tiêu. Bạn có thể định nghĩa bố cục chứa các trường bạn muốn trong tiêu đề và đặt bộ lọc trong Trình lọc để chỉ áp dụng bố cục cho thông báo đầu tiên của phiên (hoặc bạn có thể sử dụng một số kỹ thuật khác mà nó được thêm vào tệp đầu ra chỉ một lần).
Sử dụng tệp NLog.config của mình, đây là một cách mà bạn có thể đạt được những gì bạn muốn. Lưu ý rằng tôi đã không cố gắng này, vì vậy tôi không biết nếu tập tin cấu hình này là hợp lệ hoặc, nếu có, nếu nó sẽ tạo ra các kết quả mà bạn muốn.
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.mono2.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
autoReload="true"
internalLogLevel="Warn"
internalLogFile="nlog log.log"
>
<variable name="HeaderLayout" value="${processname} ${gdc:item=version} ${gdc:item=releasedate} ${windows-identity}" />
<variable name="NormalLayout" value="${longdate} ${logger} ${level} ${message} />
<targets async="true">
<target name="file" xsi:type="File" fileName="log.log"
layout="${NormalLayout}">
</target>
<target name="fileHeader" xsi:type="File" fileName="log.log"
layout="${HeaderLayout}">
</target>
</targets>
<rules>
<logger name="HeaderLogger" minlevel="Trace" writeTo="fileHeader" final="true" />
<logger name="*" minlevel="Trace" writeTo="file" />
</rules>
</nlog>
Trong code của bạn, logic khởi động của bạn có thể trông như thế này:
public void Main()
{
AddHeaderToLogFile();
}
public void AddHeaderToLogFile()
{
Logger headerlogger = LogManager.GetLogger("HeaderLogger");
//Use GlobalDiagnosticContext in 2.0, GDC in pre-2.0
GlobalDiagnosticContext["releasedate"] = GetReleaseDate();
GlobalDiagnosticContext["version"] = GetFileVersion();
GlobalDiagnosticContext["someotherproperty"] = GetSomeOtherProperty();
headerlogger.Info("message doesn't matter since it is not specified in the layout");
//Log file should now have the header as defined by the HeaderLayout
//You could remove the global properties now if you are not going to log them in any
//more messages.
}
Ý tưởng ở đây là bạn sẽ đặt các phiên bản tập tin, ngày phát hành, vv trong GDC khi chương trình bắt đầu. Đăng nhập một thông điệp bằng trình ghi "HeaderLogger". Thông báo này sẽ được ghi vào tệp nhật ký bằng cách sử dụng "HeaderLayout" vì "HeaderLogger" được liên kết với mục tiêu "fileHeader" được liên kết với "HeaderLayout". Các trường được xác định trong bố cục tiêu đề được ghi vào tệp nhật ký. Thông điệp tường trình tiếp theo, vì chúng sẽ không sử dụng "HeaderLogger", sẽ sử dụng bố cục "root" (*). Họ sẽ đi đến cùng một tệp vì cả mục tiêu "tệp" và "tệpHeader" cuối cùng đều trỏ đến cùng một tên tệp.
Trước khi tôi bắt đầu nhập phản hồi này, tôi không chắc chắn bạn có thể dễ dàng hoàn thành việc thêm tiêu đề vào tệp nhật ký của mình như thế nào. Có đánh máy này, tôi nghĩ rằng nó thực sự có thể khá dễ dàng!
Chúc may mắn!
[EDIT] Một cái gì đó như thế này có thể hoạt động để thay đổi bố cục dựa trên cấp độ. Trong phần đầu tiên, tôi đã xác định một số biến, mỗi biến xác định bố cục. Trong phần tiếp theo, tôi đã xác định một số mục tiêu mà mỗi mục tiêu sử dụng cùng một tệp, nhưng được lọc để chỉ cho phép các thông điệp của một cấp cụ thể được viết. Trong phần cuối cùng, tôi xác định một quy tắc duy nhất sẽ gửi tất cả các thông điệp (do đó có tên "logger") cho tất cả các mục tiêu.Vì mỗi mục tiêu được lọc theo cấp độ, mục tiêu "theo dõi" sẽ chỉ ghi các thông điệp "dấu vết", v.v. Vì vậy, các thông báo "theo dõi" sẽ được viết bằng cách sử dụng bố cục "theo dõi", thông báo "gỡ lỗi" sẽ được ghi bằng cách sử dụng "gỡ lỗi" bố trí, vv Vì tất cả các mục tiêu cuối cùng ghi vào cùng một tệp, tất cả các thư sẽ kết thúc trong cùng một tệp. Tôi đã không thử điều này, nhưng tôi nghĩ rằng nó có thể sẽ làm việc.
<variable name="TraceLayout" value="THIS IS A TRACE: ${longdate} ${level:upperCase=true} ${message}" />
<variable name="DebugLayout" value="THIS IS A DEBUG: ${longdate} ${level:upperCase=true} ${message}" />
<variable name="InfoLayout" value="THIS IS AN INFO: ${longdate} ${level:upperCase=true} ${message}" />
<targets async="true">
<target name="fileAsTrace" xsi:type="FilteringWrapper" condition="level==LogLevel.Trace">
<target xsi:type="File" fileName="log.log" layout="${TraceLayout}" />
</target>
<target name="fileAsDebug" xsi:type="FilteringWrapper" condition="level==LogLevel.Debug">
<target xsi:type="File" fileName="log.log" layout="${DebugLayout}" />
</target>
<target name="fileAsInfo" xsi:type="FilteringWrapper" condition="level==LogLevel.Info">
<target xsi:type="File" fileName="log.log" layout="${InfoLayout}" />
</target>
</targets>
<rules>
<logger name="*" minlevel="Trace" writeTo="fileAsTrace, fileAsDebug, fileAsInfo" />
</rules>
(Lưu ý rằng tôi chỉ bao gồm 3 cấp ở đây).
Sau khi hiển thị cách (nếu nó hoạt động, dù sao) để áp dụng bố cục khác nhau dựa trên cấp độ, điều này có vẻ giống như trường hợp sử dụng bất thường. Tôi không nói rằng đó là một ý tưởng tốt hay một ý tưởng tồi, nhưng tôi không thể nói rằng tôi đã thực sự thấy điều này được thực hiện rất nhiều. Tùy thuộc vào chính xác như thế nào bạn muốn đầu ra cuối cùng của bạn để xem xét, những gì tôi đã cho thấy bạn có thể hoặc có thể không phải là cách tốt nhất để đạt được nó. Có lẽ bạn có thể đăng một số ví dụ về cách bạn muốn đầu ra của bạn để xem xét.
Bạn cũng có thể xem xét chấp nhận câu trả lời gốc và sau đó tạo câu hỏi mới về cách bố trí đầu ra cho mỗi cấp để chúng tôi có thể tập trung thảo luận trong câu hỏi đó về vấn đề cấp/bố cục. Đó là vào bạn nếu điều đó có vẻ hữu ích hay không.
này hoạt động:
<variable name="TraceLayout" value="This is a TRACE - ${longdate} | ${logger} | ${level} | ${message}"/>
<variable name="DebugLayout" value="This is a DEBUG - ${longdate} | ${logger} | ${level} | ${message}"/>
<variable name="InfoLayout" value="This is an INFO - ${longdate} | ${logger} | ${level} | ${message}"/>
<variable name="WarnLayout" value="This is a WARN - ${longdate} | ${logger} | ${level} | ${message}"/>
<variable name="ErrorLayout" value="This is an ERROR - ${longdate} | ${logger} | ${level} | ${message}"/>
<variable name="FatalLayout" value="This is a FATAL - ${longdate} | ${logger} | ${level} | ${message}"/>
<targets>
<target name="fileAsTrace" xsi:type="FilteringWrapper" condition="level==LogLevel.Trace">
<target xsi:type="File" fileName="xxx.log" layout="${TraceLayout}" />
</target>
<target name="fileAsDebug" xsi:type="FilteringWrapper" condition="level==LogLevel.Debug">
<target xsi:type="File" fileName="xxx.log" layout="${DebugLayout}" />
</target>
<target name="fileAsInfo" xsi:type="FilteringWrapper" condition="level==LogLevel.Info">
<target xsi:type="File" fileName="xxx.log" layout="${InfoLayout}" />
</target>
<target name="fileAsWarn" xsi:type="FilteringWrapper" condition="level==LogLevel.Warn">
<target xsi:type="File" fileName="xxx.log" layout="${WarnLayout}" />
</target>
<target name="fileAsError" xsi:type="FilteringWrapper" condition="level==LogLevel.Error">
<target xsi:type="File" fileName="xxx.log" layout="${ErrorLayout}" />
</target>
<target name="fileAsFatal" xsi:type="FilteringWrapper" condition="level==LogLevel.Fatal">
<target xsi:type="File" fileName="xxx.log" layout="${FatalLayout}" />
</target>
</targets>
<rules>
<logger name="*" minlevel="Trace" writeTo="fileAsTrace,fileAsDebug,fileAsInfo,fileAsWarn,fileAsError,fileAsFatal" />
<logger name="*" minlevel="Info" writeTo="dbg" />
</rules>
Tôi đã thiết lập một Giao diện cho mỗi cấp độ khai thác gỗ, thêm một chuỗi chữ vào đầu mô tả mức độ của thông điệp (đây là để chứng minh rằng một định dạng khác nhau được sử dụng cho mỗi cấp độ). Mỗi Layout được kết hợp với một FilteringWrapper để lọc dựa trên mức độ của thông báo và hướng bất kỳ thông điệp nào vượt qua bộ lọc được ghi vào tệp đầu ra. Mỗi FilteringWrapper được gói cùng một tệp đầu ra, vì vậy tất cả các thông điệp tường trình sẽ được ghi vào cùng một tệp.
Đây là một phần của mã mà tôi sử dụng để thử nghiệm:
logger.Trace("Trace msg");
logger.Debug("Debug msg");
logger.Info("Info msg");
logger.Warn("Warn msg");
logger.Error("Error msg");
logger.Fatal("Fatal msg");
Và đây là những gì đầu ra trông giống như:
This is a TRACE - 2010-11-22 13:20:00.4131 | NLogTest.Form1 | Trace | Trace msg
This is a DEBUG - 2010-11-22 13:20:00.4131 | NLogTest.Form1 | Debug | Debug msg
This is an INFO - 2010-11-22 13:20:00.4131 | NLogTest.Form1 | Info | Info msg
This is a WARN - 2010-11-22 13:20:00.4131 | NLogTest.Form1 | Warn | Warn msg
This is an ERROR - 2010-11-22 13:20:00.4131 | NLogTest.Form1 | Error | Error msg
This is a FATAL - 2010-11-22 13:20:00.4131 | NLogTest.Form1 | Fatal | Fatal msg
Rõ ràng vấn đề về thông tin cấu hình trước đây của tôi là không gian giữa các giá trị "writeTo"
. Tôi đoán NLog rất nhạy cảm với điều này. Tôi đã có một cái gì đó như "writeTo=blah1, blah2, blah3".
Khi tôi thay đổi điều đó thành "writeTo=blah1,blah2,blah3"
lỗi đã biến mất. Chúc may mắn!
Nhiều cảm ơn salaryoghe, điều đó đã làm việc điều trị. Về cơ bản tôi cần phải có bố trí khác nhau cho các mức độ đăng nhập khác nhau, làm thế nào để bạn thực hiện bố trí có điều kiện ở cấp độ được lựa chọn? –
Bạn muốn bố cục khác nhau trông như thế nào? Bạn có muốn có các trường khác nhau trong bố cục cho các mức ghi khác nhau không? Ở mức nào, bạn có thể sử dụng kỹ thuật mà Pat hiển thị trong liên kết ở trên. Ông định nghĩa một mục tiêu tập tin cho thông điệp khai thác "bình thường" của mình và xác định mục tiêu "trình bao bọc bộ lọc" để sử dụng bố cục khác cho các thư có chứa ngoại lệ. Tôi sẽ cố gắng thêm một ví dụ về thứ gì đó có thể giúp bạn. – wageoghe
Sử dụng kỹ thuật được đề xuất, cho các mục sau: Tôi nhận được lỗi sau trong tệp cấu hình: 'Thuộc tính' writeTo 'không hợp lệ ....' cho –