Я внедрил пользовательское приложение log4net, которое пишет в службу http ... хорошо работает, но у меня есть некоторая преждевременная оптимизация в моей голове. В частности, есть ли лучший способ сделать это? Наверное, я могу убедиться, что только критические классы имеют этот конкретный apprender, но похоже, что может быть много приложений и ответственности даже с консервативными вариантами ведения журнала.log4net подробности реализации - пользовательский appender
У кого-нибудь есть опыт, который они хотели бы поделиться? Я посмотрел на http://geekswithblogs.net/michaelstephenson/archive/2014/01/02/155044.aspx, который по сути является тем, что я делаю ... (см. Код). Насколько хорошо что-то похожее на этот масштаб? Мне нравится фабрика для singleton ... как насчет реализации параллельной очереди для буферизации записей?
Надеюсь, я не буду слишком сильно отрываться от администратора, чтобы задать вопрос о потенциальном мнении.
(добавление кода из статьи разъяснений)
public class ServiceBusAppender : AppenderSkeleton
{
public string ConnectionStringKey { get; set; }
public string MessagingEntity { get; set; }
public string ApplicationName { get; set; }
public string EventType { get; set; }
public bool Synchronous { get; set; }
public string CorrelationIdPropertyName { get; set; }
protected override void Append(log4net.Core.LoggingEvent loggingEvent)
{
var myLogEvent = new AzureLoggingEvent(loggingEvent);
myLogEvent.ApplicationName = ApplicationName;
myLogEvent.EventType = EventType;
myLogEvent.CorrelationId = loggingEvent.LookupProperty(CorrelationIdPropertyName) as string;
if (Synchronous)
AppendInternal(myLogEvent, 0);
else
{
Task.Run(() => AppendInternal(myLogEvent, 0));
}
}
protected void AppendInternal(AzureLoggingEvent myLogEvent, int attemptNo)
{
try
{
//Convert event to JSON
var stream = new MemoryStream();
var json = Newtonsoft.Json.JsonConvert.SerializeObject(myLogEvent);
var writer = new StreamWriter(stream);
writer.Write(json);
writer.Flush();
stream.Seek(0, SeekOrigin.Begin);
//Setup service bus message
var message = new BrokeredMessage(stream, true);
message.ContentType = "application/json";
message.Label = myLogEvent.MessageType;
message.Properties.Add(new KeyValuePair<string, object>("ApplicationName", myLogEvent.ApplicationName));
message.Properties.Add(new KeyValuePair<string, object>("UserName", myLogEvent.UserName));
message.Properties.Add(new KeyValuePair<string, object>("MachineName", myLogEvent.MachineName));
message.Properties.Add(new KeyValuePair<string, object>("MessageType", myLogEvent.MessageType));
message.Properties.Add(new KeyValuePair<string, object>("Level", myLogEvent.Level));
message.Properties.Add(new KeyValuePair<string, object>("EventType", myLogEvent.EventType));
//Setup Service Bus Connection
var connection = ConfigurationManager.ConnectionStrings[ConnectionStringKey];
if (connection == null || string.IsNullOrEmpty(connection.ConnectionString))
{
ErrorHandler.Error("Cant publish the error, the connection string does not exist");
return;
}
var factory = MessagingFactoryManager.Instance.GetMessagingFactory(connection.ConnectionString);
var sender = factory.CreateMessageSender(MessagingEntity);
//Publish
sender.Send(message);
}
catch (Exception ex)
{
if (ex.Message.Contains("The operation cannot be performed because the entity has been closed or aborted"))
{
if (attemptNo < 3)
AppendInternal(myLogEvent, attemptNo++);
else
ErrorHandler.Error("Error occured while publishing error", ex);
}
else
ErrorHandler.Error("Error occured while publishing error", ex);
}
}
protected override void Append(log4net.Core.LoggingEvent[] loggingEvents)
{
foreach(var loggingEvent in loggingEvents)
{
Append(loggingEvent);
}
}
Thx,
Chris
Лучший способ сделать что конкретно? Не дайте нам ссылку на «в основном то, что вы делаете», поставьте блок кода в свой вопрос, показывая нам, что вы делаете. –
хорошо, ради обсуждения используйте этот код. Я хочу знать, как он масштабируется ... log4net собирается развернуть еще одно приложение для каждого класса, настроенного для этого. Я не знаю, что имеет смысл иметь кучу http-клиентов (по одному на каждого приложения), похоже на ответственность. Помните, я сказал, что знаю, что это преждевременная оптимизация ... Мне интересно, как люди делятся своим опытом с подобными решениями. –