บางส่วนตกอยู่ในหมวดหมู่ของเคล็ดลับ NLog ทั่วไป (หรือการบันทึก) แทนที่จะเป็นคำแนะนำการกำหนดค่าอย่างเคร่งครัด
นี่คือลิงค์บันทึกทั่วไปจากที่นี่ที่ SO (คุณอาจเคยเห็นลิงก์เหล่านี้บางส่วนหรือทั้งหมดแล้ว):
log4net กับ Nlog
การบันทึกแนวทางปฏิบัติที่ดีที่สุด
สิ่งที่เป็นจุดสำคัญของซุ้มทำไม้?
ทำไมคนตัดไม้แนะนำให้ใช้คนตัดไม้ต่อคลาส?
Logger logger = LogManager.GetCurrentClassLogger()
ใช้รูปแบบทั่วไปของการตั้งชื่อคนตัดไม้ของคุณขึ้นอยู่กับการเรียน สิ่งนี้จะช่วยให้คุณมีความละเอียดระดับสูงในตัวบันทึกและให้ความยืดหยุ่นอย่างมากในการกำหนดค่าตัวบันทึก (ควบคุมทั่วโลกตามเนมสเปซตามชื่อตัวบันทึกเฉพาะ ฯลฯ )
ใช้ตัวบันทึกที่ไม่ใช่ชื่อคลาสตามความเหมาะสม บางทีคุณอาจมีฟังก์ชั่นเดียวที่คุณต้องการควบคุมการบันทึกแยกต่างหาก บางทีคุณอาจมีข้อกังวลเกี่ยวกับการบันทึกแบบตัดต่อกัน (การบันทึกประสิทธิภาพ)
หากคุณไม่ได้ใช้การบันทึกแบบใช้ชื่อคลาสให้พิจารณาตั้งชื่อตัวบันทึกของคุณในโครงสร้างแบบลำดับชั้นบางประเภท (อาจตามพื้นที่การใช้งาน) เพื่อให้คุณสามารถรักษาความยืดหยุ่นในการกำหนดค่าได้มากขึ้น ตัวอย่างเช่นคุณอาจมีพื้นที่ใช้งาน "ฐานข้อมูล" การวิเคราะห์ "FA" และ "ui" FA แต่ละเหล่านี้อาจมีพื้นที่ย่อย ดังนั้นคุณอาจขอคนตัดไม้แบบนี้:
Logger logger = LogManager.GetLogger("Database.Connect");
Logger logger = LogManager.GetLogger("Database.Query");
Logger logger = LogManager.GetLogger("Database.SQL");
Logger logger = LogManager.GetLogger("Analysis.Financial");
Logger logger = LogManager.GetLogger("Analysis.Personnel");
Logger logger = LogManager.GetLogger("Analysis.Inventory");
และอื่น ๆ ด้วยตัวบันทึกลำดับชั้นคุณสามารถกำหนดค่าการบันทึกทั่วโลก ("*" หรือ root logger) โดย FA (ฐานข้อมูลการวิเคราะห์ UI) หรือตามพื้นที่ย่อย (Database.Connect ฯลฯ )
ตัวบันทึกมีตัวเลือกการกำหนดค่ามากมาย:
<logger name="Name.Space.Class1" minlevel="Debug" writeTo="f1" />
<logger name="Name.Space.Class1" levels="Debug,Error" writeTo="f1" />
<logger name="Name.Space.*" writeTo="f3,f4" />
<logger name="Name.Space.*" minlevel="Debug" maxlevel="Error" final="true" />
ดูวิธีใช้NLogสำหรับข้อมูลเพิ่มเติมเกี่ยวกับความหมายของตัวเลือกแต่ละตัว อาจเป็นสิ่งที่น่าสังเกตมากที่สุดของที่นี่คือความสามารถในการใช้กฎตัวแทนคนตัดไม้แนวคิดที่ว่ากฎคนตัดไม้หลายคนสามารถ "ดำเนินการ" สำหรับคำสั่งการบันทึกเดียวและกฎการบันทึกสามารถทำเครื่องหมายว่า "สุดท้าย" ดังนั้นกฎต่อมา รับงบการบันทึก
ใช้ GlobalDiagnosticContext, MappedDiagnosticContext และ NestedDiagnosticContext เพื่อเพิ่มบริบทเพิ่มเติมให้กับเอาต์พุตของคุณ
ใช้ "ตัวแปร" ในไฟล์กำหนดค่าของคุณเพื่อทำให้ง่ายขึ้น ตัวอย่างเช่นคุณอาจกำหนดตัวแปรสำหรับโครงร่างของคุณแล้วอ้างอิงตัวแปรในการกำหนดค่าเป้าหมายแทนที่จะระบุเค้าโครงโดยตรง
<variable name="brief" value="${longdate} | ${level} | ${logger} | ${message}"/>
<variable name="verbose" value="${longdate} | ${machinename} | ${processid} | ${processname} | ${level} | ${logger} | ${message}"/>
<targets>
<target name="file" xsi:type="File" layout="${verbose}" fileName="${basedir}/${shortdate}.log" />
<target name="console" xsi:type="ColoredConsole" layout="${brief}" />
</targets>
หรือคุณสามารถสร้างชุดคุณสมบัติ "กำหนดเอง" เพื่อเพิ่มลงในเค้าโครง
<variable name="mycontext" value="${gdc:item=appname} , ${mdc:item=threadprop}"/>
<variable name="fmt1withcontext" value="${longdate} | ${level} | ${logger} | [${mycontext}] |${message}"/>
<variable name="fmt2withcontext" value="${shortdate} | ${level} | ${logger} | [${mycontext}] |${message}"/>
หรือคุณสามารถทำสิ่งต่าง ๆ เช่นสร้างตัวเรนเดอร์เค้าโครง "วัน" หรือ "เดือน" อย่างเคร่งครัดผ่านการกำหนดค่า:
<variable name="day" value="${date:format=dddd}"/>
<variable name="month" value="${date:format=MMMM}"/>
<variable name="fmt" value="${longdate} | ${level} | ${logger} | ${day} | ${month} | ${message}"/>
<targets>
<target name="console" xsi:type="ColoredConsole" layout="${fmt}" />
</targets>
คุณสามารถใช้เลย์เอาต์การแสดงเพื่อกำหนดชื่อไฟล์ของคุณ:
<variable name="day" value="${date:format=dddd}"/>
<targets>
<target name="file" xsi:type="File" layout="${verbose}" fileName="${basedir}/${day}.log" />
</targets>
หากคุณหมุนไฟล์ทุกวันไฟล์แต่ละไฟล์อาจมีชื่อว่า "Monday.log", "Tuesday.log" ฯลฯ
อย่ากลัวที่จะเขียนเค้าร่างของคุณเอง มันเป็นเรื่องง่ายและช่วยให้คุณสามารถเพิ่มข้อมูลบริบทของคุณเองไปยังไฟล์บันทึกผ่านการกำหนดค่า ตัวอย่างเช่นนี่คือตัวแสดงโครงร่าง (ตาม NLog 1.x ไม่ใช่ 2.0) ที่สามารถเพิ่ม Trace.CorrelationManager.ActivityId ลงในบันทึก:
[LayoutRenderer("ActivityId")]
class ActivityIdLayoutRenderer : LayoutRenderer
{
int estimatedSize = Guid.Empty.ToString().Length;
protected override void Append(StringBuilder builder, LogEventInfo logEvent)
{
builder.Append(Trace.CorrelationManager.ActivityId);
}
protected override int GetEstimatedBufferSize(LogEventInfo logEvent)
{
return estimatedSize;
}
}
บอก NLog ว่าส่วนขยาย NLog ของคุณอยู่ที่ไหน (แอสเซมบลีใด) เช่นนี้
<extensions>
<add assembly="MyNLogExtensions"/>
</extensions>
ใช้ตัวสร้างเค้าโครงที่กำหนดเองดังนี้:
<variable name="fmt" value="${longdate} | ${ActivityId} | ${message}"/>
ใช้เป้าหมาย async:
<nlog>
<targets async="true">
<!-- all targets in this section will automatically be asynchronous -->
</targets>
</nlog>
และ wrappers เป้าหมายเริ่มต้น:
<nlog>
<targets>
<default-wrapper xsi:type="BufferingWrapper" bufferSize="100"/>
<target name="f1" xsi:type="File" fileName="f1.txt"/>
<target name="f2" xsi:type="File" fileName="f2.txt"/>
</targets>
<targets>
<default-wrapper xsi:type="AsyncWrapper">
<wrapper xsi:type="RetryingWrapper"/>
</default-wrapper>
<target name="n1" xsi:type="Network" address="tcp://localhost:4001"/>
<target name="n2" xsi:type="Network" address="tcp://localhost:4002"/>
<target name="n3" xsi:type="Network" address="tcp://localhost:4003"/>
</targets>
</nlog>
ที่เหมาะสม. ดูเอกสาร NLog สำหรับข้อมูลเพิ่มเติมเกี่ยวกับเอกสารเหล่านั้น
บอก NLog ให้ดูและโหลดการกำหนดค่าใหม่โดยอัตโนมัติหากมีการเปลี่ยนแปลง:
<nlog autoReload="true" />
มีตัวเลือกการกำหนดค่าหลายอย่างที่จะช่วยแก้ไขปัญหา NLog
<nlog throwExceptions="true" />
<nlog internalLogFile="file.txt" />
<nlog internalLogLevel="Trace|Debug|Info|Warn|Error|Fatal" />
<nlog internalLogToConsole="false|true" />
<nlog internalLogToConsoleError="false|true" />
ดูวิธีใช้ NLog สำหรับข้อมูลเพิ่มเติม
NLog 2.0 เพิ่มการห่อหุ้ม LayoutRenderer ที่ช่วยให้การประมวลผลเพิ่มเติมที่จะดำเนินการในการส่งออกของการแสดงผลเค้าโครง (เช่นการตัดช่องว่างการตัดตัวพิมพ์ใหญ่ตัวพิมพ์เล็ก ฯลฯ )
อย่ากลัวที่จะปิดตัวบันทึกถ้าคุณต้องการป้องกันรหัสของคุณจากการพึ่งพาอย่างหนักใน NLog แต่ห่ออย่างถูกต้อง มีตัวอย่างวิธีห่อในพื้นที่เก็บข้อมูล github ของ NLog เหตุผลอื่นในการตัดคำอาจเป็นเพราะคุณต้องการเพิ่มข้อมูลบริบทเฉพาะลงในแต่ละข้อความที่บันทึกไว้โดยอัตโนมัติ (โดยใส่ลงใน LogEventInfo.Context)
มีข้อดีข้อเสียของการตัด (หรือสรุป) NLog (หรือกรอบงานการบันทึกอื่น ๆ สำหรับเรื่องนั้น) ด้วยความพยายามเพียงเล็กน้อยคุณสามารถค้นหาข้อมูลมากมายได้ที่นี่เพื่อนำเสนอทั้งสองด้าน
หากคุณกำลังพิจารณาตัดพิจารณาใช้Common.Logging มันทำงานได้ค่อนข้างดีและช่วยให้คุณสามารถสลับไปยังเฟรมเวิร์กการบันทึกอื่นได้อย่างง่ายดายหากคุณต้องการ นอกจากนี้หากคุณกำลังพิจารณาการห่อคิดเกี่ยวกับวิธีที่คุณจะจัดการกับวัตถุบริบท (GDC, MDC, NDC) Common.Logging ไม่สนับสนุน abstraction สำหรับพวกเขาในปัจจุบัน แต่คาดว่าจะเพิ่มความสามารถในคิว