Índice
¿Qué es el ArchestrA Log Viewer?
El Log Viewer es el sistema centralizado de registro de AVEVA System Platform e InTouch. Todos los componentes de la plataforma (Application Server, Historian, InTouch, etc.) vuelcan sus mensajes aquí, se pueden consultar, filtrar y configurar qué queremos registrar, ejemplo de la librería que vamos a crear, por defecto vienen esos tres checkboxes activados.
Cuando desarrollamos una librería .NET o creamos un nuevo componente .NET que extiende funcionalidades al Application Server / InTouch, lo más limpio es integrarse con este Logger en lugar de escribir en un fichero propio. Para eso vamos a utilizar la propia librería que ya hace esta función en todos sus componentes: LoggerDLL.dll.
Aquí tenemos el ejemplo de los métodos que vamos a utilizar para luego entender mejor nuestra clase en C#:
Crear el proyecto Class Library (.NET Framework)
Creamos un proyecto de tipo Class Library (.NET Framework) en Visual Studio. El framework debe ser compatible con la versión de AVEVA instalada (actualmente .NET Framework 4.8).
Voy a mostrar solo el ejemplo de una función dentro de la librería que estamos creando, donde lo más importante es la llamada a la clase que vamos a crear para escribir en el Logger:
La clase AvevaLogger
El siguiente código es la clase que puedes copiar en tu proyecto, añade una referencia a LoggerDLL.dll (ubicada en C:\Program Files (x86)\Common Files\ArchestrA\LoggerDLL.dll) y ya tienes los cuatro niveles de log disponibles como métodos estáticos.
La clase se auto-inicializa en la primera llamada, registra el cliente con el nombre del ensamblado y se desregistra automáticamente al cerrar el proceso gracias al evento ProcessExit.
using System;
using System.Reflection;
using System.Runtime.InteropServices;
namespace PHSTraining
{
internal class AvevaLogger
{
private const string LoggerDllPath = @"C:\Program Files (x86)\Common Files\ArchestrA\LoggerDLL.dll";
private static int _hIdentity = 0;
private static bool _initialized = false;
private static string _identityName = string.Empty;
static AvevaLogger()
{
AppDomain.CurrentDomain.ProcessExit += OnProcessExit;
}
[DllImport(LoggerDllPath, EntryPoint = "REGISTERLOGGERCLIENT")]
private static extern int RegisterLoggerClient(ref int hIdentity);
[DllImport(LoggerDllPath, EntryPoint = "UNREGISTERLOGGERCLIENT")]
private static extern int UnregisterLoggerClient(ref int hIdentity);
[DllImport(LoggerDllPath, EntryPoint = "SETIDENTITYNAME", CharSet = CharSet.Unicode)]
private static extern int SetIdentityName(int hIdentity, string identityName);
[DllImport(LoggerDllPath, EntryPoint = "LOGINFO", CharSet = CharSet.Unicode)]
private static extern void LogInfo(int hIdentity, string message);
[DllImport(LoggerDllPath, EntryPoint = "LOGWARNING", CharSet = CharSet.Unicode)]
private static extern void LogWarning(int hIdentity, string message);
[DllImport(LoggerDllPath, EntryPoint = "LOGERROR", CharSet = CharSet.Unicode)]
private static extern void LogError(int hIdentity, string message);
[DllImport(LoggerDllPath, EntryPoint = "LOGTRACE", CharSet = CharSet.Unicode)]
private static extern void LogTrace(int hIdentity, string message);
public static void LogInfo(string message)
{
EnsureInitialized();
LogInfo(_hIdentity, message ?? string.Empty);
}
public static void LogWarning(string message)
{
EnsureInitialized();
LogWarning(_hIdentity, message ?? string.Empty);
}
public static void LogError(string message)
{
EnsureInitialized();
LogError(_hIdentity, message ?? string.Empty);
}
public static void LogTrace(string message)
{
EnsureInitialized();
LogTrace(_hIdentity, message ?? string.Empty);
}
private static void EnsureInitialized()
{
if (_initialized) return;
_identityName = Assembly.GetExecutingAssembly().GetName().Name;
int rc = RegisterLoggerClient(ref _hIdentity);
if (rc <= 0 || _hIdentity == 0)
throw new InvalidOperationException("REGISTERLOGGERCLIENT failed.");
rc = SetIdentityName(_hIdentity, _identityName);
if (rc <= 0)
throw new InvalidOperationException("SETIDENTITYNAME failed.");
_initialized = true;
}
private static void OnProcessExit(object sender, EventArgs e)
{
if (_hIdentity != 0)
UnregisterLoggerClient(ref _hIdentity);
_hIdentity = 0;
_initialized = false;
_identityName = string.Empty;
}
}
}
Después de agregar la clase a tu proyecto, ya puedes acabar tu librería / User Control, compilarlo e importarlo a System Platform.
Una vez importada verás que se ha copiado en:
C:\Program Files (x86)\ArchestrA\Framework\FileRepository\[GalaxyName]\Vendors\ArchestrA
Y también podrás comprobar que existe en la siguiente ruta:
C:\Users\Administrator\AppData\Local\Temp\ScriptTemp
donde se generan automáticamente el .aaSLIB y el XML.
Ahora solo nos falta probarla e implementarla donde corresponda. Este sería el ejemplo:
Un Script que vamos a forzar con el Object Viewer.
Y la salida en el Log Viewer :-)
Agradecimientos
Por último y no menos importante:
«La gratitud en silencio no sirve a nadie.» — Gladys Berthe Stern
Quiero dar las gracias a mi compañero Ivan Comino Martinez. Estas son las paradojas del destino:
«Cuando trabajaba en Telstar (Syntegon), un gran abrazo para todos los que lo lean, Ivan Comino trabajaba en Systel, y en más de una ocasión me tocó ver código y programas que habían desarrollado y en los comentarios lo primero que leía era "IC" y yo pensaba... ¡Qué bueno, qué buen trabajo! Y ahora tengo la suerte de tenerlo como compañero, aprender con él y trabajar en equipo.» — José Manuel Luque