2010-09-17 15 views
10

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; 
} 
+0

¿Podría publicar el código que instala los contadores, y también el código que los actualiza? –

+1

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. –

+0

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. –

Respuesta

12

Los contadores de rendimiento se basan en segmentos de memoria compartida. He visto problemas similares cuando alguien todavía tiene un control para el segmento de memoria compartida. Esto puede incluir la herramienta perfmon en sí misma. Puede usar la utilidad de control para ver quién está reteniendo la memoria compartida. No debería necesitar reiniciar, intente ver si este problema desaparece si cierra perfmon primero y luego vuelve a crear los contadores. También asegúrese de que su servicio no se esté ejecutando.

+0

¡Dulce Cristo! ¡Muchas gracias !, ni siquiera quiero decirte cuánto tiempo pasé en esto antes de encontrar esta respuesta. Al final, tuve que cerrar perfmon, cerrar la sesión de PowerShell que estaba accediendo al contador, detener una aplicación web en IIS y reciclar la AppPool. Nada funcionó hasta que hice CADA una de esas cosas. –

3

Antes de la respuesta de Mike, manejé el problema yo mismo. Pero no tengo tiempo para descubrir la causa del problema. He resuelto el problema mediante la realización de los pasos siguientes:

  1. parada de registro Monitor de rendimiento (Me he registrado todas mis contadores a través de registrador de Monitor de rendimiento)
  2. cerca perfmon
  3. servicio de desinstalación (toda contadores de rendimiento del servicio de desinstalación de desinstalación del grupo)
  4. servicio de instalación con contadores de rendimiento adicionales

Después de estos pasos, aparecen nuevos contadores de rendimiento como deberían. Tal vez no sea necesario detener el registro, pero no tengo tiempo para comprobarlo por el momento. Lo intentaré más tarde. Acepto la respuesta de Mike como correcta ya que apunta a la causa del problema.

1

Tuve un caso similar en el que creé algunos contadores de rendimiento para diferentes segmentos de mi sistema y los agregué a un diccionario para acceso directo por nombre, y todos escribieron uno a todos (cualquier incremento en cualquiera de ellos se actualizaría el resto).

Para mi sorpresa que la solución era CERRAR el Monitor de rendimiento de la herramienta ventanas y luego crear los contadores. El problema era una memoria compartida usada que estaba bloqueada.

Cuestiones relacionadas