рддреБрд░рдВрдд рдкрд░реАрдХреНрд╖рдг рдХреЗ рдорд╛рд╣реМрд▓ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЖрд░рдХреНрд╖рдг рдХрд░реЗрдВ, рдХреНрдпреЛрдВрдХрд┐ рдореЗрд░реЗ рддрд░реНрдХреЛрдВ рдореЗрдВ рдореИрдВ рдкрд░реАрдХреНрд╖рд╛ рдкрд░рд┐рдгрд╛рдореЛрдВ рдкрд░ рднрд░реЛрд╕рд╛ рдХрд░реВрдВрдЧрд╛ред I7 рдкреНрд░реЛрд╕реЗрд╕рд░ (4 рдХреЛрд░, 8 рд╣рд╛рдЗрдкрд░-рдереНрд░реЗрдбрд┐рдВрдЧ рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрддреЗ рд╣реБрдП), log4net.Extensions.Console рдПрдкреНрд▓рд┐рдХреЗрд╢рди 8 рдереНрд░реЗрдб рдореЗрдВ рд▓реЙрдЧ рдСрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд▓рд┐рдЦрддрд╛ рд╣реИ, рдЬреЛ рдордирдорд╛рдиреЗ рдврдВрдЧ рд╕реЗ рдиреАрдВрдж рдХреЗ рдмрд╛рдж рд░рд┐рдХреЙрд░реНрдбрд┐рдВрдЧ рдХрд░рддрд╛ рд╣реИред рд▓реЙрдЧ рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐рдпреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ 10000 рд╣реИред BulkStarter рдПрдкреНрд▓рд┐рдХреЗрд╢рди log4net.Extensions.Console рдФрд░ рдЙрдирдХреЗ рдкреВрд░рд╛ рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП рдЗрдВрддрдЬрд╛рд░ рдХрд░ рд░рд╣рд╛ рд╣реИ рдХреЗ 10 рдЙрджрд╛рд╣рд░рдг рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИред рдЗрд╕ рдкреНрд░рдХрд╛рд░, 10 рдкреНрд░рдХреНрд░рд┐рдпрд╛рдПрдВ, рдкреНрд░рддреНрдпреЗрдХ рдореЗрдВ 8 рдереНрд░реЗрдбреНрд╕ рдХреЗ рд╕рд╛рде, рдПрдХ рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рд▓рд┐рдЦреЗрдВред рд╕реНрдЯреЙрдкрд╡реЙрдЪ (рдЙрдкрд╛рдпреЛрдВ рдХреЗ рд▓рд┐рдП рдЙрдЪреНрдЪ-рд░рд┐рдЬрд╝реЙрд▓реНрдпреВрд╢рди рдЯрд╛рдЗрдорд░) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЗрд╕ рддрд░рд╣ рдХреЗ рдкрд░реАрдХреНрд╖рдг рдореЗрдВ рд╕рднреА рд╕рдордп рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред
FileAppender + MinimalLock
Log4net рдореЗрдВ, рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рд▓реЙрдЧ рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдлрд╛рдЗрд▓рдПрдкреЗрдВрдбрд░ рд╣реИред рдпрд╣ рдПрдХ рд╡рд┐рд╢реЗрд╖ рд▓реЙрдХ (рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рдкреНрд░рдпреБрдХреНрдд) рдФрд░ рддрдерд╛рдХрдерд┐рдд рдорд┐рдирд┐рдорд▓реЙрдХ рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИред Log4net рдХреЛ рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝ рдХрд░рддреЗ рд╕рдордп, ExclusiveLock рдЕрдиреНрдп рдкреНрд░рдХреНрд░рд┐рдпрд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдХреЗрд╡рд▓-рдкрдврд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдлрд╝рд╛рдЗрд▓ рдЦреЛрд▓рддрд╛ рд╣реИред рдорд┐рдирд┐рдорд▓реЙрдХ рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдкреНрд░рддреНрдпреЗрдХ рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐ рдХреЗ рд▓рд┐рдП рдлрд╝рд╛рдЗрд▓ рдЦреЛрд▓рдиреЗ / рдмрдВрдж рдХрд░рдиреЗ рдХрд╛ рдХрд╛рд░реНрдп рдХрд░рддрд╛ рд╣реИред рддрджрдиреБрд╕рд╛рд░, рдПрдХреНрд╕рдХреНрд▓реВрд╕рд┐рд╡рд▓реЙрдХ рд╣рдореЗрдВ рдмрд┐рд▓реНрдХреБрд▓ рднреА рд╕реВрдЯ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ (рдХреНрдпреЛрдВрдХрд┐ рдлрд╝рд╛рдЗрд▓ рдкрд╣рд▓реЗ рд╡рд╛рд▓реА рд╕рднреА рдкреНрд░рдХреНрд░рд┐рдпрд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдЕрдиреБрдкрд▓рдмреНрдз рд╣реЛрдЧреА рдЬреЛ рдлрд╝рд╛рдЗрд▓ рдкрд░ рд▓реЙрдХ рдХреЛ рдХреИрдкреНрдЪрд░ рдХрд░рддреА рд╣реИ), рдФрд░ рдорд┐рдирд┐рдорд▓реЙрдХ рдореЗрдВ рдХрдИ рдЧрдВрднреАрд░ рдХрдорд┐рдпрд╛рдВ рд╣реИрдВ:
- рдмрд╣реБрдд рдзреАрдорд╛ (рдкрд░реАрдХреНрд╖рдг рдХреЗ 1:56 рд╕реЗ, рд▓реЙрдЧрд┐рдВрдЧ рд╡рд┐рдзрд┐ рдореЗрдВ рд╕реАрдзреЗ рдХреЙрд▓ 1:40 рд▓рд┐рдпрд╛ рдЧрдпрд╛);
- рдПрдХ рд▓реЙрдХ рд╕рдВрдШрд░реНрд╖ рдЬрдм рдХрдИ рдкреНрд░рдХреНрд░рд┐рдпрд╛рдПрдВ рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдзрд╛рдЧрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░рддреА рд╣реИрдВ (рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рд▓реЙрдЧ рдХреЗ рд▓рд┐рдП рд▓реЗрдЦрди рдирд╣реАрдВ)ред
<appender name="FileAppender" type="log4net.Appender.FileAppender"> <file value="D:\1\test-minlock.log"/> <lockingModel type="log4net.Appender.FileAppender+MinimalLock" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%message%n"/> </layout> </appender>
ConcurrentMinimalLock
рдПрдХ рдпреЛрдЧреНрдп рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрди рдХреА рддрд▓рд╛рд╢ рдореЗрдВ, рдореИрдВ рдХреЛрдб рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдкрд░ 2008 рдХреЗ рдПрдХ рд▓реЗрдЦ рдореЗрдВ рдЖрдпрд╛ - рдмрд╣реБ-рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд╕реЗ рдПрдХрд▓ рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рд▓реЙрдЧрд┐рдВрдЧ ред рд▓реЗрдЦ рдореЗрдВ рд╕рдорд╡рд░реНрддреА рдореИрдирд┐рдорд▓реЙрдХ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХрд╛ рд╡рд░реНрдгрди рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рд╕рдВрджреЗрд╢ рдмрдлрд╝рд░ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ, рдФрд░ рдлрд╝рд╛рдЗрд▓ рдХреЛ рд▓реВрдк рдореЗрдВ рдЦреЛрд▓рд╛ рдЬрд╛рддрд╛ рд╣реИ (рдЬрдм рддрдХ рдХрд┐ рд▓реЙрдХ рд╕реНрдерд╛рдкрд┐рдд рдирд╣реАрдВ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ)ред рд╕рдм рдХреБрдЫ рдареАрдХ рд▓рдЧ рд░рд╣рд╛ рд╣реИ, рд▓реЗрдХрд┐рди рд▓реЙрдЧрд┐рдВрдЧ рд╡рд┐рдзрд┐ рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХрд╛ рд╕рдордп 1:20 рдореЗрдВ рд╕реЗ 1:04 рд╣реИред рдпрд╛рдиреА рдЕрднреА рднреА рд▓рдВрдмрд╛ рд╣реИред рдФрд░ рдпрд╣ рдЗрд╕ рддрдереНрдп рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦ рд░рд╣рд╛ рд╣реИ рдХрд┐ рдпрд╣ рдЖрдВрд╢рд┐рдХ рд░реВрдк рд╕реЗ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рд▓реЙрдЧрд┐рдВрдЧ рд╣реИ (рдпрджрд┐ рдЖрд╡реЗрджрди рд╣рд╛рд░реНрдб-рдмрдВрдж рд╣реИ, рддреЛ рд╕рднреА рдХрддрд╛рд░реЗрдВ рдЦреЛ рдЬрд╛рдПрдВрдЧреА)ред
ConcurrentFileAppender
рдореЗрд░реЗ рд╢реЛрдз рдореЗрдВ рдореБрдЭреЗ рдмрд╣реБрдд рдЖрд╢реНрдЪрд░реНрдп рд╣реБрдЖ рдХрд┐ рдХреЛрдИ рднреА рдореНрдпреВрдЯреЗрдЯ рдореНрдпреВрдЯреЗрдХреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЙрдирдХрд╛ рдореБрдЦреНрдп рдЙрджреНрджреЗрд╢реНрдп рдХреНрд░реЙрд╕-рдкреНрд░реЛрд╕реЗрд╕ рд╕рд┐рдВрдХреНрд░рдирд╛рдЗрдЬрд╝реЗрд╢рди рд╣реИред рдЗрд╕рд▓рд┐рдП, рдореИрдВрдиреЗ рдЕрдкрдирд╛ рдЦреБрдж рдХрд╛ рдРрдкреЗрдВрдбрд░ рд▓рд┐рдЦрдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛, рдЬреЛ рдореНрдпреВрдЯреЗрдХреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкреНрд░рдХреНрд░рд┐рдпрд╛рдУрдВ рдХреЗ рдмреАрдЪ рддрд╛рд▓рдореЗрд▓ рдмреИрдард╛рдПрдЧрд╛ред рдПрдХ рдЕрдкреНрдкреЗрдиреНрдбрд░ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:
- рдЕрдореВрд░реНрдд рд╡рд░реНрдЧ log4net.Appender.AppenderSkeleton рд╕реЗ рдирд┐рд╣рд┐рдд;
- ActivateOptions рдкрджреНрдзрддрд┐ рдХреЛ рд▓рд╛рдЧреВ рдХрд░реЗрдВ, рдЬрд┐рд╕рдореЗрдВ рдкрд░рд┐рд╢рд┐рд╖реНрдЯ рдХрд╛ рдкреНрд░рд╛рд░рдВрдн рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ;
- рдПрдХ рдПрдХрд▓ LoggingEvent рдФрд░ LoggingEvent рдХреА рдПрдХ рд╕рд░рдгреА рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рддрд░реАрдХреЛрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд░реЗрдВред
- OnClose рдкрджреНрдзрддрд┐ рдХреЛ рд▓рд╛рдЧреВ рдХрд░реЗрдВ, рдЬреЛ рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХреЛ рд╕рд╛рдл рдХрд░рддрд╛ рд╣реИ (log4net рдореЗрдВ рдирд┐рдкрдЯрд╛рди рдХреЗ рд╕рдорд╛рди)ред
ActivateOptions
рдЖрд░рдВрднреАрдХрд░рдг рдХреЗ рд╕рдордп, рд╣рдо рдлрд╛рдЗрд▓рд╕реНрдЯреНрд░реАрдо рдХреЛ рд░рд╛рдЗрдЯ рдореЛрдб рдореЗрдВ рдЦреЛрд▓рддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдлрд╛рдЗрд▓рд╢реЗрдпрд░ рдХреЛ рд░реАрдб-рд░рд╛рдЗрдЯ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рддреЗ рд╣реИрдВред рдпрд╛рдиреА рдЕрдиреНрдп рдкреНрд░рдХреНрд░рд┐рдпрд╛рдПрдБ рдЗрд╕ рдлрд╝рд╛рдЗрд▓ рдХреЛ рд╕рдорд╛рдирд╛рдВрддрд░ рдореЗрдВ рдкрдврд╝рдиреЗ-рд▓рд┐рдЦрдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдВрдЧреАред рдпрд╣ рдЕрдлрд╝рд╕реЛрд╕ рдХреА рдмрд╛рдд рд╣реИ рдХрд┐ рдХрд┐рд╕реА рдХреЗ рд▓рд┐рдП рд░реАрдб-рдУрдирд▓реА рдлрд╝рд╛рдЗрд▓ рдмрдирд╛рдиреЗ рдХрд╛ рдХреЛрдИ рддрд░реАрдХрд╛ рдирд╣реАрдВ рд╣реИ рдЬреЛ рдЙрди рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рд╕рдорд╡рд░реНрддреА рдлрд╝рд╛рдЗрд▓реЗрдиреНрдбрд░ рдирд╣реАрдВ рд╣реИред рд╕рдорд░реНрдерди рдСрдирд▓рд╛рдЗрди (рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ) рдлрд╛рдЗрд▓реЛрдВ рдХреЛ рд╕рдВрдкрд╛рджрд┐рдд рдирд╣реАрдВ рдХрд░ рд╕рдХрд╛ред рддрдереНрдп рдпрд╣ рд╣реИ рдХрд┐ рд╣рдо рдлрд╝рд╛рдЗрд▓ рдХреЛ рдЦреБрд▓рд╛ рд░рдЦрддреЗ рд╣реИрдВ, рд╣рдореЗрдВ рдмрд╣реБрдд рд╕рдордп рдЦреЛрд▓рдиреЗ рдореЗрдВ рдЦрд░реНрдЪ рдирд╣реАрдВ рдХрд░рдиреЗ рдХрд╛ рдЕрд╡рд╕рд░ рджреЗрддрд╛ рд╣реИ, рдЬреИрд╕рд╛ рдХрд┐ рдкрд┐рдЫрд▓реЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред
public override void ActivateOptions() Dispose(true); // flush base.ActivateOptions(); // var path = SystemInfo.ConvertToFullPath(Path); var dir = System.IO.Path.GetDirectoryName(path); if (!Directory.Exists(dir)) Directory.CreateDirectory(dir); _loggingEvents = new Queue<LoggingEvent>(QueueInitialCapacity); FileStream stream = null; Mutex mutex = null; try { stream = File.Open(path, FileMode.Append, FileAccess.Write, FileShare.ReadWrite); mutex = CreateMutex(path); _thread = new Thread(ThreadProc) { Name = "ConcurrentFileAppenderListener", IsBackground = true // logging thread should not prevent an application exit }; _thread.Start(); _stream = stream; stream = null; _mutex = mutex; mutex = null; if (FlushOnProcessExit) AppDomain.CurrentDomain.ProcessExit += delegate { OnProcessExit(path); }; } finally { if (stream != null) stream.Dispose(); if (mutex != null) mutex.Close(); } }
ThreadProc
рд▓реВрдк рдореЗрдВ рд╡рд┐рдзрд┐ рдЯреНрд░рд╛рдЗрдЯ рдЧреИрд░-рд╢реВрдиреНрдпрддрд╛ рдХреЗ рд▓рд┐рдП рдХрддрд╛рд░ рдХреА рдЬрд╛рдВрдЪ рдХрд░рддреА рд╣реИред рдпрджрд┐ рдХрддрд╛рд░ рдЦрд╛рд▓реА рдирд╣реАрдВ рд╣реИ, рддреЛ рдЗрд╕рдХреА рд╕рд╛рдордЧреНрд░реА рдХреА рдкреНрд░рддрд┐рд▓рд┐рдкрд┐ рдмрдирд╛рдПрдБ, рдЗрд╕реЗ рд╕рд╛рдлрд╝ рдХрд░реЗрдВ рдФрд░ рдЗрд╕реЗ рдбрд┐рд╕реНрдХ рдкрд░ рдбрдВрдк рдХрд░реЗрдВред
private void ThreadProc() { var culture = CultureInfo.InvariantCulture; while (true) { if (!_nonEmptyQueue) // bool { Thread.Sleep(QueueEmptyCheckTimeoutInMilliseconds); continue; } lock (QueueSyncRoot) { _currentProcessingEvents = _loggingEvents.ToArray(); _loggingEvents.Clear(); _nonEmptyQueue = false; } Flush(_mutex, _stream, culture, _currentProcessingEvents); _currentProcessingEvents = null; } }
рд▓рд╛рд▓рд┐рдорд╛
рдХрддрд╛рд░ рдореЗрдВ рд╕рдВрдЪрд┐рдд рд╕рдВрджреЗрд╢реЛрдВ рдХреЛ рдкрд╣рд▓реЗ рдмрдлрд░ рдХреЛ рд▓рд┐рдЦрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рдлрд┐рд░ рдЗрд╕ рдмрдлрд░ рдХреЛ рдбрд┐рд╕реНрдХ рдХреЛ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЖрд╡рдВрдЯрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рддрд╛рдХрд┐ рдЙрддреНрддрд░рд╛рдзрд┐рдХрд╛рд░реА рдХреЙрд▓ рди рдХрд░реЗрдВред рд░рд┐рдХреЙрд░реНрдбрд┐рдВрдЧ рд╕реЗ рдкрд╣рд▓реЗ рд╕реАрдХ рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдФрд░ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдмрд┐рдВрджреБ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдлрд╝рд╛рдЗрд▓ рдХрд░реНрд╕рд░ рдХреА рд╡рд░реНрддрдорд╛рди рд╕реНрдерд┐рддрд┐ рдХреИрд╢ рдХреА рдЧрдИ рд╣реИред
private void Flush(Mutex mutex, FileStream stream, CultureInfo culture, ICollection<LoggingEvent> events) { if (events.Count <= 0) return; byte[] buffer; using (var sw = new StringWriter(culture)) { foreach (var e in events) RenderLoggingEvent(sw, e); buffer = Encoding.GetBytes(sw.ToString()); } try { mutex.WaitOne(); stream.Seek(0, SeekOrigin.End); stream.Write(buffer, 0, buffer.Length); stream.Flush(); } finally { mutex.ReleaseMutex(); } }
рдЕрдВрддрд┐рдо рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди
рдЕрдВрдд рдореЗрдВ, рдмреЗрд╕ рдХреНрд▓рд╛рд╕ ConcurrentAppenderSkeleton рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рдерд╛:
public abstract class ConcurrentAppenderSkeleton : AppenderSkeleton, IDisposable { /// <summary> /// Gets a name for a <see cref="Mutex"/>. /// </summary> protected abstract string UniqueMutexName { get; } /// <summary> /// Performs initialization of an appender. Should throw exception if cannot be initialized. /// </summary> protected abstract void ActivateOptionsInternal(); /// <summary> /// Prepares data to a flushing. /// </summary> /// <remarks> /// <para>This method executes in a thread safe context (under <see cref="Monitor"/> lock).</para> /// </remarks> /// <param name="events">Logging events.</param> /// <returns>A prepared data.</returns> protected abstract object PrepareData(LoggingEvent[] events); /// <summary> /// Flushes prepared data. /// </summary> /// <remarks> /// <para>This method executes in a thread-safe context (under mutex).</para> /// </remarks> /// <param name="data">A prepared data to a flushing.</param> protected abstract void Flush(object data); }
рдФрд░ рдЗрдирд╣реЗрд░рд┐рдЯрд░реНрд╕: ConcurrentFileAppender рдФрд░ ConcurrentForwardingAppender ( BufferingForwardingAppender рдХреЗ рд╕рдорд╛рди)ред рдЙрддреНрддрд░рд╛рд░реНрджреНрдз рдЖрдкрдХреЛ рдЕрдиреНрдп рдкрд░рд┐рд╢рд┐рд╖реНрдЯреЛрдВ рдХреЗ рд╕рдореВрд╣ рдХреЛ рд▓рд┐рдЦрдиреЗ (рдлреНрд▓рд╢) рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдпрд╣ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИ рдХрд┐ рдпреЗ рдЕрдиреНрдп рдкрд░рд┐рд╢рд┐рд╖реНрдЯ рдЕрдирдиреНрдп рддрд╛рд▓реЗ рдирд╣реАрдВ рдмрдирд╛рддреЗ рд╣реИрдВ (рдпрд╛рдиреА рдлрд╝рд╛рдЗрд▓рдПрдкреЗрдВрдбрд░ + рдПрдХреНрд╕рдХреНрд▓реВрд╕рд┐рд╡рд▓реЙрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ), рдФрд░ рдЗрд╕рд▓рд┐рдП рдЙрдиреНрд╣реЗрдВ рдореНрдпреВрдЯреЗрдХреНрд╕ рджреНрд╡рд╛рд░рд╛ рд╕рд┐рдВрдХреНрд░рдирд╛рдЗрдЬрд╝ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред
рдкрд░реАрдХреНрд╖рдг рдХреЗ рдкреНрд░рдпреЛрдЬрдиреЛрдВ рдХреЗ рд▓рд┐рдП, рдореИрдВрдиреЗ рдПрдХ рд╕реЗрдЯрд┐рдВрдЧ рдЬреЛрдбрд╝реА - рдЬрд┐рд╕рдореЗрдВ рдореНрдпреВрдЯреЗрдХреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕рд┐рдВрдХреНрд░рдирд╛рдЗрдЬрд╝ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрдЧрд╣ рд╣реИ: рдпрд╛ рддреЛ рдХрддрд╛рд░ рд╕реЗ рд╕рдВрджреЗрд╢ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рд╕реЗ рддреБрд░рдВрдд рдкрд╣рд▓реЗ, рдпрд╛ рдХреЗрд╡рд▓ рдПрдХ рдлрд╝рд╛рдЗрд▓ рдкрд░ рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдПред рдкрд╣рд▓реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдХрддрд╛рд░реЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рд╡реГрджреНрдзрд┐ рд╣реБрдИ рд╣реИ (рд▓рдВрдмреЗ рд╕рдордп рддрдХ рддрд╛рд▓реЗ рдХреЗ рдХрд╛рд░рдг, рдХреНрдпреЛрдВрдХрд┐ рд╡реЗ рд╕реНрд╡рд░реВрдкрдг рдФрд░ рд░рд┐рдХреЙрд░реНрдбрд┐рдВрдЧ рд╢рд╛рдорд┐рд▓ рд╣реИрдВ), рд▓реЗрдХрд┐рди рдЗрдирдкреБрдЯ / рдЖрдЙрдЯрдкреБрдЯ рд▓рд╛рдЧрдд рдореЗрдВ рдХреБрдЫ рдХрдореА (10Kb рдХреЗ 10 рд░рд┐рдХреЙрд░реНрдб 100 рд╕реЗ 1Kb рд╕реЗ рдЕрдзрд┐рдХ рддреЗрдЬ рд╣реИрдВ)ред рджреВрд╕рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдХрддрд╛рд░ рдмрд╣реБрдд рдЕрдзрд┐рдХ рдирд╣реАрдВ рдмрдврд╝рддреА рд╣реИ, рддрд╛рд▓рд╛ рдореЗрдВ рд╣реЛрдирд╛ рдХрдо рд╕реЗ рдХрдо рд╣реИ (рдХреЗрд╡рд▓ I / O рд╕реНрд╡рдпрдВ рдХреЗ рд▓рд┐рдП рд╕рдордп), рдЬреЛ рдЕрдзрд┐рдХ рд╕реНрдХреЗрд▓реЗрдмрд▓ рд╣реИред
рдХрд╕реМрдЯреА
рдЖрдкрдХреЛ рдпрд╛рдж рджрд┐рд▓рд╛ рджреВрдВ рдХрд┐ рдПрдХ рдкрд░реАрдХреНрд╖рдг рдореЗрдВ 8 рдзрд╛рдЧреЗ рдХреЗ рд╕рд╛рде 10 рдкреНрд░рдХреНрд░рд┐рдпрд╛рдУрдВ рдХреА 500 рдПрдордмреА рд▓реЙрдЧ рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐ рд╣реИред рдиреАрдЪреЗ рджреА рдЧрдИ рддрд╛рд▓рд┐рдХрд╛ рд╡рд┐рднрд┐рдиреНрди рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЗ рд▓рд┐рдП рдкрд░рд┐рдгрд╛рдо рджрд┐рдЦрд╛рддреА рд╣реИред ConcurrentFileAppender рдХреЛ рдлрд╛рдЗрд▓ рдХреЗ рд░реВрдк рдореЗрдВ рд╕рдВрдХреНрд╖рд┐рдкреНрдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, ConcurrentForwardingAppender (рд░рд┐рдХреЙрд░реНрдбрд┐рдВрдЧ FileAppender + MinimalLock рдореЗрдВ Fwd + Min рдХреЗ рд░реВрдк рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ), рдФрд░ рд╡рд┐рджреЗрд╢реА рд╕рдВрд╕реНрдХрд░рдг ConcurrentForwardingAppender рд╣реИ, рдЬрд╣рд╛рдВ рд░рд┐рдХреЙрд░реНрдбрд┐рдВрдЧ рд╕рдорд░реВрдкрдореИрдВрдорд┐рд▓реЙрдХ рдХреЗ рд╕рд╛рде FileAppender рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЗрд╕реЗ Fwd + Con рдХреЗ рд░реВрдк рдореЗрдВ рдирд╛рдорд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдХрддрд╛рд░рдмрджреНрдз рдорддрджрд╛рди рдХреЗ рд▓рд┐рдП рдиреАрдВрдж рдХрд╛ рд╕рдордп 10ms рд╣реИред Mutex.WaitOne рдХреЛ рдХреЗрд╡рд▓ рд░рд┐рдХреЙрд░реНрдбрд┐рдВрдЧ рдХреЗ рд▓рд┐рдП IO рдХреЗ рд░реВрдк рдореЗрдВ рдирд╛рдорд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рд╕реНрд╡рд░реВрдкрдг рдФрд░ рд░рд┐рдХреЙрд░реНрдбрд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рд╕рдВрдкреВрд░реНрдгред
рд╕рдордп (s) \ Test | MinLock | рд╕рдорд╡рд░реНрддреА рдорд┐рдирд▓реЛрдХ | рдлрд╝рд╛рдЗрд▓ io | рдкреВрд░реА рдлрд╛рдЗрд▓ | Fwd + рдорд┐рдирдЯ io | Fwd + рдорд┐рдирдЯ рдкреВрд░реЗ | Fwd + con io | Fwd + рдХреЛрди рдкреВрд░рд╛ |
---|---|---|---|---|---|---|---|---|
рдХреБрд▓ рд╕рдордп | 116.6 | 79.7 | 11.27 | 11.6 | 11.96 | 11.61 | 11.7 | 11.61 |
logger.Debug | 100.36 | 64.68 | 0.08 | 0.07 | 0.07 | 0.07 | 0.08 | 0.07 |
рдмреБрдз рдХрддрд╛рд░ рдХреА рд▓рдВрдмрд╛рдИ | - | - | 9 | 40 | 185 | 169 | 17 | 25 |
рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рддрд╛рд▓рд┐рдХрд╛ рд╕реЗ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдХреЗрд╡рд▓ рдЗрдирдкреБрдЯ-рдЖрдЙрдЯрдкреБрдЯ рдХреА рдЕрд╡рдзрд┐ рдХреЗ рд▓рд┐рдП рдореНрдпреВрдЯреЗрдХреНрд╕ рд▓реЙрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп, рд╕рдВрджреЗрд╢ рдХрддрд╛рд░ рдЫреЛрдЯреА рд╣реЛрддреА рд╣реИ, рдЬреЛ рд╡рд┐рд╢реНрд╡рд╕рдиреАрдпрддрд╛ рдХреЛ рдереЛрдбрд╝рд╛ рдмрдврд╝рд╛рддреА рд╣реИред рдпрджрд┐ рдЖрдкрдХреЛ RollingFileAppender рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рддреЛ рдпрд╣ ConcurrentMorimalLock рдХреЗ рд╕рд╛рде рд╕рдВрдпреЛрдЬрди рдХреЗ рд░реВрдк рдореЗрдВ ConcurrentForwardingAppender рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдордЭ рдореЗрдВ рдЖрддрд╛ рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐ рд▓реЙрдХ рдХреЗ рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рд╕рдВрд╕реНрдХрд░рдг рдХреЛ рд▓рд┐рдЦрдирд╛ рдмреЗрд╣рддрд░ рд╣реИ, рдЬреЛ рджреЛрд╣рд░рд╛рд╡ рдирд╣реАрдВ рдХрд░реЗрдЧрд╛ред
рд╕рдорд╡рд░реНрддреА * рдПрдкреЗрдВрдбрд░реНрд╕ рдХреЗ рджреЛ рдореБрдЦреНрдп рд▓рд╛рдн: рд▓реЙрдЧрд┐рдВрдЧ рд╕рдХреНрд╖рдо рд╣реЛрдиреЗ рдкрд░ рдореБрдЦреНрдп рдЕрдиреБрдкреНрд░рдпреЛрдЧ рдореЗрдВ рдорд▓реНрдЯреАрдкреНрд░реЛрд╕реЗрд╕рд┐рдВрдЧ рдФрд░ рдордВрджреА рдХреА рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рдЕрдиреБрдкрд╕реНрдерд┐рддрд┐ред
рдкреБрдирд╢реНрдЪ
рдПрдХ рд▓реЗрдЦ рд▓рд┐рдЦрдиреЗ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ, рдореИрдВрдиреЗ рдХреБрд▓ рд╕рдордп рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдФрд░ рд▓рдХрдбрд╝рд╣рд╛рд░рд╛.рдмрдмрдЧ рд╡рд┐рдзрд┐ рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдореЗрдВ рдПрдХ рддреНрд░реБрдЯрд┐ рджреЗрдЦреАред рдореЗрд░реЗ рдРрдкреЗрдВрдбрд░реНрд╕ рдХреЗ рд╕рд╛рде, рд╕рдм рдХреБрдЫ рдФрд░ рднреА рдмрджрддрд░ рд╣реЛ рдЧрдпрд╛, рд▓реЗрдХрд┐рди рдореЗрд░рд╛ рдФрд░ рднреА рдмреЗрд╣рддрд░ рдХреЗ рд╕рд╛рде :) рд▓реЗрдХрд┐рди рдореИрдВрдиреЗ рдореВрд▓ рдкрд░рд┐рдгрд╛рдо рддрд╛рд▓рд┐рдХрд╛ рдХреЛ рдЕрдм рдФрд░ рдЕрдкрдбреЗрдЯ рдирд╣реАрдВ рдХрд┐рдпрд╛, рдХреНрдпреЛрдВрдХрд┐ рдмрд╣реБрдд рд▓рдВрдмреЗ рд╕рдордп рдХреЗ рд▓рд┐рдП, рдЦреЗрдж рд╣реИ (рддреНрд░реБрдЯрд┐ рдпрд╣ рд╣реИ рдХрд┐ log4net.Extensions.Console рд╕реНрдЯреЙрдкрд╡реЙрдЪ рдЗрдВрд╕реНрдЯреЗрдВрд╕ рддрдХ рдкрд╣реБрдВрдЪ рдХреЛ рдЕрд╕рдВрдпрдорд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ + рдпрд╣ рдорд╛рди 8 рд╕реЗ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рдерд╛)ред
рд╕рдВрджрд░реНрдн:
- Log4net рдЖрдзрд┐рдХрд╛рд░рд┐рдХ рдкреЗрдЬ
- System.Threading.Mutex - рдПрдХ рд╡рд░реНрдЧ рдЬреЛ .NET рдлреНрд░реЗрдорд╡рд░реНрдХ рдореЗрдВ рдореНрдпреВрдЯреЗрдХреНрд╕ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИ
- рдорд▓реНрдЯреА-рдкреНрд░реЛрд╕реЗрд╕ рд╕реЗ рд╕рд┐рдВрдЧрд▓ рдлрд╛рдЗрд▓ рдореЗрдВ рд▓реЙрдЧ рдЗрди рдХрд░рдирд╛