c# - studio - Actualizar el nombre de archivo de destino NLog en tiempo de ejecución
para que sirve el archivo app config (6)
La razón por la que recibe el error es que NLog no sabe nada sobre el nombre de clave "logDirectory" . Puede implementarlo usted mismo (lea las instrucciones here ) o use las predefinidas desde here .
Luego, puede usar las instrucciones desde here para cambiar los objetivos de NLog durante el tiempo de ejecución.
En mi solicitud, trabajo en varios miles de documentos al día. Me gustaría, en algunos casos, algunos registros, un registro por documento. Luego me gustaría, para un objetivo específico, cambiar el nombre de archivo de salida (y solo el nombre de archivo) en el tiempo de ejecución.
En la red encontré cómo crear un objetivo programándome. Me gustaría actualizar el nombre del archivo mediante la programación. Probé el siguiente código. El error que recibo es "LayoutRender no se puede encontrar ''logDirectory''.
Alguna idea ?
Gracias,
var target = (FileTarget)LogManager.Configuration.FindTargetByName("logfile");
target.FileName = "${logDirectory}/file2.txt";
LoggingConfiguration config = new LoggingConfiguration();
var asyncFileTarget = new AsyncTargetWrapper(target);
config.AddTarget("logfile", asyncFileTarget);
LogManager.Configuration = config;
El archivo de configuración es:
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<variable name="logDirectory" value="C:/MyLogs"/>
<targets>
<target name="logfile" xsi:type="File" layout="${date:format=dd/MM/yyyy HH/:mm/:ss.fff}|${level}|${stacktrace}|${message}" fileName="${logDirectory}/file.txt" />
</targets>
<rules>
<logger name="*" minlevel="Info" writeTo="logfile" />
</rules>
</nlog>
Para cualquier persona atrapada en esto, finalmente encontré una solución. Estaba intentando actualizar algunas configuraciones de destino de syslog en el tiempo de ejecución y nada estaba funcionando. La simple actualización de la configuración no funciona, debe restablecer el objeto de Configuración, que es tan simple como hacer esto:
LogManager.Configuration = LogManager.Configuration;
Esto hace que un evento interno se dispare y use la configuración actualizada.
Pruebe el método ReconfigExistingLoggers
:
var target = (FileTarget)LogManager.Configuration.FindTargetByName("logfile");
target.FileName = "${logDirectory}/file2.txt";
LogManager.ReconfigExistingLoggers();
Como está escrito en los documentos:
Recorre todos los registradores devueltos previamente por GetLogger. y vuelve a calcular su lista de destino y filtro. Es útil después de modificar la configuración mediante programación para garantizar que todos los registradores se hayan configurado correctamente.
EDITAR :
Intente usar el renderizador de diseño personalizado: archivo de configuración NLog para obtener los valores de configuración de configuración de un web.config
Si no necesita cambiar el LogDirectory en tiempo de ejecución, puede hacer esto:
target.FileName = "${var:logDirectory}//file2.txt");
Si necesita modificar el directorio de registro en tiempo de ejecución, use el GDC:
https://github.com/NLog/NLog/wiki/Gdc-layout-renderer
NLog.GlobalDiagnosticsContext.Set("logDirectory","C:/Temp/");
Luego puedes usar el siguiente diseño:
target.FileName = "${gdc:item=logDirectory}//file2.txt";
Resulta que he escrito una respuesta que se ajusta a tu pregunta también .
En esencia, en lugar de intentar reescribir la configuración, sería mejor que simplemente creara una configuración que le permita elegir dinámicamente el nombre de archivo que desea.
Un ejemplo adaptado para su caso de uso:
Logger myLog = LogManager.GetLogger(name);
LogLevel level = LogLevel.Error;
string message = "This is an error message!";
LogEventInfo
esta información en un objeto LogEventInfo
:
LogEventInfo logEvent = new LogEventInfo(level , myLog.Name, message);
Luego puede agregar propiedades a este evento (los índices de cadena se pueden elegir libremente):
logEvent.Properties["CustomFileName"] = "mycustomfilename";
Y luego escribes en el log:
myLog.Log(logEvent);
Lo interesante aquí es que en su configuración de NLog, puede usar esta propiedad personalizada en cualquier campo al que la documentación de Nlog se refiere como un valor de "Disposición" .
Utiliza ${event-properties:item=CustomFileName}
en el diseño para acceder a la propiedad. Por ejemplo:
<target xsi:type="File"
name="file"
fileName="${basedir}/logs/${event-properties:item=CustomFileName}.log"
layout="${message}" />
Siguiendo el ejemplo publicado, este mensaje se registrará en el archivo mycustomfilename.log
. Esto le permite cambiar dinámicamente su archivo de destino a su gusto configurando el valor logEvent.Properties["CustomFileName"]
a cualquier nombre de archivo que desee usar.
Tenga en cuenta que puede optimizar esto aún más, y por ejemplo, solo podrá elegir parte del nombre del archivo.
El beneficio adicional es que solo necesita un objetivo y una regla en su archivo de configuración para que esto funcione.
Tony''s solución Tony''s no parece funcionar si usas NLog Async ( <targets async="true">
target <targets async="true">
). Tuve que usar el destino del contenedor para obtener mi FileTarget, de lo contrario obtengo muchos errores. Estoy usando NLog 2.1.
if (LogManager.Configuration != null && LogManager.Configuration.ConfiguredNamedTargets.Count != 0)
{
Target target = LogManager.Configuration.FindTargetByName("yourFileName");
if (target == null)
{
throw new Exception("Could not find target named: " + "file");
}
FileTarget fileTarget = null;
WrapperTargetBase wrapperTarget = target as WrapperTargetBase;
// Unwrap the target if necessary.
if (wrapperTarget == null)
{
fileTarget = target as FileTarget;
}
else
{
fileTarget = wrapperTarget.WrappedTarget as FileTarget;
}
if (fileTarget == null)
{
throw new Exception("Could not get a FileTarget from " + target.GetType());
}
fileTarget.FileName = "SetFileNameHere";
LogManager.ReconfigExistingLoggers();
}
Esto tampoco cambia el archivo de configuración, solo cambia el valor de tiempo de ejecución. Así que también edito manualmente el archivo de configuración a mi nuevo valor usando el siguiente código:
var nlogConfigFile = "NLog.config";
var xdoc = XDocument.Load(nlogConfigFile);
var ns = xdoc.Root.GetDefaultNamespace();
var fTarget = xdoc.Descendants(ns + "target")
.FirstOrDefault(t => (string)t.Attribute("name") == "yourFileName");
fTarget.SetAttributeValue("fileName", "SetFileNameHere");
xdoc.Save(nlogConfigFile);