2010-05-18 14 views
6

Estoy usando log4net appender ADO.NET para registrar mensajes de Azure Worker Role en la instancia de SQL Azure (los diagnósticos predeterminados simplemente no encajan). Por alguna razón, al ejecutar el worker en dev fabric, el logging funciona. Sin embargo, cuando la instancia se implementa en la nube (con exactamente la misma configuración) los errores no se registran.log4net ADO.NET Appender funciona en Dev Fabric, pero falla silenciosamente en Azure

configuración sucede en el código utilizando este archivo:

<?xml version="1.0" encoding="utf-8" ?> 
<log4net> 
    <renderer renderingClass="{ExceptionRenderer}" renderedClass="System.Exception" /> 
    <appender name="TraceAppender" type="log4net.Appender.TraceAppender"> 
    <layout type="log4net.Layout.PatternLayout"> 
     <!--<conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />--> 
     <conversionPattern value="%message%newline" /> 
    </layout> 
    </appender> 
    <appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender"> 
    <bufferSize value="3" /> 
    <connectionType value="{ConnectionType}" /> 
    <connectionString value="{ConnectionString}" /> 
    <commandText value="INSERT INTO Salescast_Log ([Date],[Thread],[Version],[Level],[Logger],[Message],[Exception]) VALUES (@log_date, @thread, '{Version}',@log_level, @logger, @message, @exception)" /> 
    <parameter> 
     <parameterName value="@log_date" /> 
     <dbType value="DateTime" /> 
     <layout type="log4net.Layout.RawTimeStampLayout" /> 
    </parameter> 
    <parameter> 
     <parameterName value="@thread" /> 
     <dbType value="String" /> 
     <size value="255" /> 
     <layout type="log4net.Layout.PatternLayout"> 
     <conversionPattern value="%thread" /> 
     </layout> 
    </parameter> 
    <parameter> 
     <parameterName value="@log_level" /> 
     <dbType value="String" /> 
     <size value="50" /> 
     <layout type="log4net.Layout.PatternLayout"> 
     <conversionPattern value="%level" /> 
     </layout> 
    </parameter> 
    <parameter> 
     <parameterName value="@logger" /> 
     <dbType value="String" /> 
     <size value="255" /> 
     <layout type="log4net.Layout.PatternLayout"> 
     <conversionPattern value="%logger" /> 
     </layout> 
    </parameter> 
    <parameter> 
     <parameterName value="@message" /> 
     <dbType value="String" /> 
     <size value="4000" /> 
     <layout type="log4net.Layout.PatternLayout"> 
     <conversionPattern value="%message" /> 
     </layout> 
    </parameter> 
    <parameter> 
     <parameterName value="@exception" /> 
     <dbType value="String" /> 
     <size value="4000" /> 
     <layout type="{ExceptionLayoutType}" /> 
    </parameter> 
    <filter type="log4net.Filter.LevelRangeFilter"> 
     <levelMin value="ERROR" /> 
     <levelMax value="FATAL" /> 
    </filter> 
    </appender> 
    <root> 
    <level value="DEBUG" /> 
    <appender-ref ref="TraceAppender" /> 
    <appender-ref ref="AdoNetAppender" /> 
    </root> 
</log4net> 

log4net se inicializa con los valores adecuados, cuando se initalized el medio ambiente Autofac COI (por inicio papel). El código se ve así:

static ILogProvider BuildProvider(IComponentContext context) 
{ 
    var connection = context 
    .Resolve<IProvideBusSettings>() 
    .GetString("SqlConnection") 
    .ExposeException("Failed to get SQL string for logging"); 

    var xml = Properties.Resources.Logging 
    .Replace("{ConnectionType}", typeof(SqlConnection).AssemblyQualifiedName) 
    .Replace("{ConnectionString}", connection) 
    .Replace("{ExceptionLayoutType}", typeof(LoggingTrimmedExceptionLayout).AssemblyQualifiedName) 
    .Replace("{ExceptionRenderer}", typeof(LoggingExceptionRenderer).AssemblyQualifiedName) 
    .Replace("{Version}", SystemDescriptor.Default.Version.ToString()); 

    var doc = new XmlDocument(); 
    doc.LoadXml(xml); 
    XmlConfigurator.Configure(doc.DocumentElement); 
    return new LoggingProvider(); 
} 

Se utiliza el sistema operativo Azure por defecto. Las conexiones SQL son obviamente válidas.

¿Alguien podría pensar en razón, por qué log4net registra los errores del tejido dev, pero no puede hacerlo desde el sistema operativo azure, utilizando exactamente los mismos archivos de configuración de servicio?

+0

¿Alguna suerte con esto? Estoy teniendo el mismo problema. – Nick

+0

No mucho. Se dejó completamente log4net a favor de un registrador personalizado simple. –

Respuesta

0

¿Podría ser un problema con sus reglas de firewall de SQL Azure?

+0

Lamentablemente, no. Los gestores de mandatos de CQRS utilizan la misma cadena de conexión de SQL Azure dentro de la misma función de trabajador sin ningún problema tanto en la estructura dev como en los escenarios azul. –

3

Puedo tener una ventaja en este tema. Permití el registro interno para log4net como se describe en here. El registro funcionaría por un tiempo y luego se detendría. El error causante en el registro log4net fue:

log4net:ERROR [log4netDbAppender] Failed in DoAppend System.Data.SqlClient.SqlException (0x80131904): A transport-level error has occurred when sending the request to the server. (provider: TCP Provider, error: 0 - An established connection was aborted by the software in your host machine.) at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection) at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning() at System.Data.SqlClient.TdsParserStateObject.WriteSni() at System.Data.SqlClient.TdsParserStateObject.ExecuteFlush() at System.Data.SqlClient.TdsParser.TdsExecuteRPC(_SqlRPC[] rpcArray, Int32 timeout, Boolean inSchema, SqlNotificationRequest notificationRequest, TdsParserStateObject stateObj, Boolean isCommandProc) at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async) at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result) at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult result, String methodName, Boolean sendToPipe) at System.Data.SqlClient.SqlCommand.ExecuteNonQuery() at log4net.Appender.AdoNetAppender.SendBuffer(IDbTransaction dbTran, LoggingEvent[] events) at log4net.Appender.AdoNetAppender.SendBuffer(LoggingEvent[] events)
at log4net.Appender.BufferingAppenderSkeleton.Append(LoggingEvent loggingEvent) at log4net.Appender.AppenderSkeleton.DoAppend(LoggingEvent loggingEvent)

Parece que log4net deja de intentar después de encontrar este error. El artículo This describe una forma de tratar este tipo de excepción en general y esto podría usarse para extender AdoNetAppender.

EDITAR Lo que podría ayudar es establecer AdoNetAppender.ReconnectOnError = cierto, es falso por defecto.

13

Me acabo de topar con esto y pasé la mayor parte del día tratando de resolverlo. Todo se redujo al hecho de que SQL Azure requiere índices agrupados en sus tablas. El código SQL de ejemplo proporcionado por log4net para crear la tabla de registro no tiene un índice agrupado, que es un requisito para SQL Azure. La adición de cualquier información a la tabla fallará a menos que tenga un índice agrupado (a partir del momento en que se escribe).

Intente hacer una instrucción de inserción manual utilizando SQL Server Management Studio mientras está conectado a SQL Azure y le indicará de inmediato si este es el problema. Si es así, ejecute el siguiente SQL para agregar un índice agrupado en la tabla (suponiendo que utilizó el SQL directo de log4net) y luego intente de nuevo.

CREATE UNIQUE CLUSTERED INDEX PK_Log ON [Log] 
    ([Id]) 
GO 
+0

¡Gracias por sugerir probar una inserción manual! –

Cuestiones relacionadas