¿Cómo obtener la ruta del archivo de destino actual utilizando NLog en tiempo de ejecución?


Utilizo NLog con la siguiente configuración:

  <targets>
    <target xsi:type="File" name="f" fileName="${basedir}/logs/${shortdate}.log"
            layout="${longdate} ${uppercase:${level}} ${message}" />
  </targets>
  <rules>
    <logger name="*" minlevel="Trace" writeTo="f" />
  </rules>

Traté de obtener FileName propiedad de FileTarget (compruebo, que solo hay un FileTarget en la colección)

NLog.LogManager.GetCurrentClassLogger().Info("test");
var logFile = (from t in NLog.LogManager.Configuration.AllTargets
                where t is NLog.Targets.FileTarget
                select (NLog.Targets.FileTarget)t).FirstOrDefault();

Pero archivo de registro.FileName contiene solo el patrón del nombre del archivo, exactamente como se especifica en configuración.

¿Cómo puedo obtener la ruta en tiempo de ejecución del archivo de registro actual?

 40
Author: Julian, 2012-07-12

4 answers

Esto hizo el truco para mí:

var fileTarget = (FileTarget) LogManager.Configuration.FindTargetByName("file");
// Need to set timestamp here if filename uses date. 
// For example - filename="${basedir}/logs/${shortdate}/trace.log"
var logEventInfo = new LogEventInfo {TimeStamp = DateTime.Now}; 
string fileName = fileTarget.FileName.Render(logEventInfo);
if (!File.Exists(fileName))
    throw new Exception("Log file does not exist.");
 51
Author: Mike,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-07-24 10:57:27

Este método funcionará incluso si ha establecido async="true" (es decir, su destino está envuelto por un AsyncTargetWrapper) en su configuración XML de NLog:

    private string GetLogFileName(string targetName)
    {
        string fileName = null;

        if (LogManager.Configuration != null && LogManager.Configuration.ConfiguredNamedTargets.Count != 0)
        {
            Target target = LogManager.Configuration.FindTargetByName(targetName);
            if (target == null)
            {
                throw new Exception("Could not find target named: " + targetName);
            }

            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());
            }

            var logEventInfo = new LogEventInfo { TimeStamp = DateTime.Now };
            fileName = fileTarget.FileName.Render(logEventInfo);
        }
        else
        {
            throw new Exception("LogManager contains no Configuration or there are no named targets");
        }

        if (!File.Exists(fileName))
        {
            throw new Exception("File " + fileName + " does not exist");
        }

        return fileName;
    }
 25
Author: markmuetz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-05-09 13:01:52

Sé que mi respuesta no es exactamente responder a la pregunta, pero lo más difícil es encontrar el objetivo correcto y lanzarlo correctamente, entonces podemos acceder a cualquier propiedad. Tampoco encontré una pregunta que se ajustara a mi respuesta, publicando aquí...

Este método funcionará incluso si ha establecido async="true" (es decir, su destino está envuelto por un AsyncTargetWrapper o cualquier TargetWrapper) en su configuración XML de NLog:

Usando la versión de NLog: 3.1.0.0

Versión en tiempo de ejecución: v4.0. 30319

    private Target FindTargetByName(string targetName)
    {
        if (LogManager.Configuration == null)
            return null;

        Target t = LogManager.Configuration.FindTargetByName(targetName);

        if (t is NLog.Targets.Wrappers.WrapperTargetBase)
        {
            var list = LogManager.Configuration.AllTargets.ToList();
            t = list.Find(x => x.Name == targetName + "_wrapped");
            return t;
        }
        else
        {
            return t;
        }
    }

Uso para MailTarget llamado emailError

var emailError = (MailTarget)FindTargetByName("emailError");
emailError.SmtpServer = "" //you can set or get
 1
Author: Pawel Cioch,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-01-23 00:34:33

Los destinos se pueden empaquetar varias veces (en mi caso, tenía un filtro), por lo que el siguiente fragmento es un enfoque más genérico para desenvolver que funciona para varios niveles y no hace suposiciones sobre los nombres de destino.

Target target = LogManager.Configuration.FindTargetByName(targetName);
while ((target != null) && (target is WrapperTargetBase))
{
    target = (target as WrapperTargetBase).WrappedTarget;
}
 1
Author: Skip,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-19 23:53:53