Tengo un problema extraño al crear nuevos contadores en un grupo existente. Tengo un servicio de Windows, que hace un poco de trabajo y me permite controlar su estado a través del contador de rendimiento. Tengo el grupo de contadores de rendimiento y algunos contadores de rendimiento. El grupo se crea durante la fase de instalación del servicio (con privilegios de administrador) y los contadores se inicializan cuando se inicia el servicio (como usuario de LocalSystem). Todo funciona bien, el grupo existe, el contador existe también, puedo monitorearlos y escribir en el registro de contadores de rendimiento. El servicio se ejecuta constantemente.Contador de rendimiento creado pero no funciona hasta que se reinicia Windows
Luego quiero agregar algunos contadores de rendimiento más. Los agrego en el código de servicio, reconstruyo y despliego al servidor desinstalando la instancia de servicio anterior (el código de desinstalación borra el grupo de contadores de rendimiento) e instalando nuevamente el servicio (el grupo de contadores de rendimiento se crea durante la fase de instalación con todos los contadores nuevos). Entonces comienzo el servicio.
Ese es el final de la parte común y poco interesante de la historia. Las cosas extrañas comienzan aquí.
Voy a PerMon, agrego todos los contadores a la vista del monitor del sistema. Puedo ver mi grupo de contadores de rendimiento, veo todos los contadores de rendimiento, incluyendo NUEVOS contadores de rendimiento que acabo de agregar. Puedo agregarlos a la vista del monitor del sistema. Y puedo ver que los viejos contadores funcionan. Pero los nuevos contadores no funcionan, no recopilan ningún dato. Bueno, vale, tal vez fue mi error, cambio a la vista de registro y trato de registrar los datos de los contadores de rendimiento. Los contadores antiguos se registran como se registraron anteriormente. Pero cuando intento agregar nuevo contador, encuentro en Visor de sucesos siguiente advertencia:
El servicio no pudo agregar el contador '\ AGENT \ MyCountersGroupName \ MyNewCounter' en el registro NewCountersLog o alerta. Este registro o alerta continuará, pero los datos de ese contador no se recopilarán. El error devuelto es: no se pudo encontrar el contador especificado.
Intenté volver a instalar el servicio, eliminar los contadores antiguos, volver a agregarlos y nada cambió. Los contadores antiguos funcionan, y los nuevos contadores no funcionan. ¡Entonces reinicio Windows y los contadores nuevos comenzaron a funcionar! Nada cambió en el servicio, acabo de reiniciar el servidor. Encontré este problema en 2 servidores, ambos se están ejecutando bajo Windows Server 2003 SP1. El código para todos los contadores de rendimiento es idéntico, porque los creo usando código con genéricos.
Puede decir "hey, no se moleste, reinicie su Windows cada vez que necesite agregar nuevos contadores de rendimiento", pero no puedo. Mi servicio se ejecuta en el servidor junto con otros servicios, y necesitamos que estos servicios funcionen constantemente, no podemos reiniciar el servidor cada vez que cambio un servicio.
¿Alguien puede ayudar con este problema?
Actualización: Parece que ahí está el problema similar: https://stackoverflow.com/questions/2180005/adding-performance-counters-to-existing-category
actualización No creo que el problema está en mi código, pero si ayuda he puesto aquí.
Código de instalar y desinstalar (llamado durante la fase de instalación): PerformanceCountersManagerBase.GetCreationData() es un contenedor genérico para la obtención de recogida de datos para crear contadores de rendimiento.
public static void Install()
{
CounterCreationDataCollection counters = new CounterCreationDataCollection(
PerformanceCountersManagerBase.GetCreationData<TManager>().ToArray());
if (PerformanceCounterCategory.Exists(PerformanceCountersManagerBase.GroupName))
PerformanceCounterCategory.Delete(PerformanceCountersManagerBase.
PerformanceCounterCategory.Create(PerformanceCountersManagerBase.GroupName,
"Group description",
PerformanceCounterCategoryType.SingleInstance, counters);
}
public static void Uninstall()
{
if (!PerformanceCounterCategory.Exists(PerformanceCountersManagerBase.GroupName))
return;
PerformanceCounterCategory.Delete(PerformanceCountersManagerBase.GroupName);
}
código para inicializar los contadores en servicio y actualización
internal void Initialize(string name, string groupName)
{
_counter = new PerformanceCounter(groupName, name, false);
_counter.RawValue = 0;
}
internal void Increment()
{
if ((_counter == null) || _counter.ReadOnly)
return;
lock (_counter)
{
_counter.Increment();
}
}
Actualización 3 he cambiado el código para instalar contadores través de los componentes .NET PerformanceCounterInstaller, y nada ha cambiado. Los contadores antiguos funcionan mientras trabajaban, y los recién creados no funcionan e intentan registrarlos en el mensaje de error exacto (advertencia) en el registro de eventos. El código de creación del instalador es el siguiente:
public static PerformanceCounterInstaller GetInstaller()
{
PerformanceCounterGroupAttribute group
= PerformanceCountersManagerBase.ExtractGroupSettings(typeof(TManager));
PerformanceCounterInstaller installer = new PerformanceCounterInstaller();
installer.CategoryName = group.Name;
installer.CategoryHelp = group.Description;
installer.CategoryType = PerformanceCounterCategoryType.SingleInstance;
installer.UninstallAction = UninstallAction.Remove;
installer.Counters.AddRange(PerformanceCountersManagerBase.GetCreationData<TManager>().ToArray());
return installer;
}
¿Podría publicar el código que instala los contadores, y también el código que los actualiza? –
Esperaba que su lógica de instalación usara 'PerformanceCounterInstaller'. ¿Por qué no estás usando eso? Lo uso para un escenario muy similar y funciona bien. –
Hm, me perdí esta clase mientras leía sobre los contadores de rendimiento. Lo intentaré el lunes, quizás pueda instalar contadores correctamente. Gracias por el consejo. Informaré sobre los resultados. –