using System;
using System.Collections.Generic;
using System.Text;
using Weborb.Messaging.Server.Adapter;
using Weborb.Messaging.Api.Service;
using System.Timers;
using Weborb.Messaging.Api;
using Weborb.Messaging.Server;
using System.Diagnostics;
using System.Collections;
using Weborb.Util.Logging;
namespace Weborb.Management.Monitoring.Performance
{
public class AppHandler : ApplicationAdapter, IPendingServiceCallback
{
Timer timer = new Timer();
Dictionary<IConnection, Subscription> subscribers;
Dictionary<String, PerformanceCounter> counters;
public AppHandler()
{
timer.Interval = 100;
timer.Elapsed += new ElapsedEventHandler( OnTimer );
subscribers = new Dictionary<IConnection, Subscription>();
counters = new Dictionary<string, PerformanceCounter>();
timer.Start();
}
void OnTimer( object sender, ElapsedEventArgs e )
{
lock( subscribers )
{
foreach( IConnection connection in subscribers.Keys )
{
Hashtable countersValue = new Hashtable();
Subscription subscription = subscribers[ connection ];
if( subscription.NextEventTime > DateTime.Now )
continue;
foreach( String counterName in subscription.Counters )
{
PerformanceCounter performanceCounter = counters[ counterName ];
countersValue[ counterName ] = performanceCounter.NextValue();
}
subscription.NextEventTime = subscription.NextEventTime.AddMilliseconds( subscription.UpdateFrequency );
if( countersValue.Count == 0 )
continue;
((IServiceCapableConnection)connection).invoke( "CountersUpdated", new object[] { countersValue } );
}
}
}
public override void appDisconnect( IConnection conn )
{
lock( subscribers )
{
subscribers.Remove( conn );
}
}
public List<String> getCounterCategories()
{
List<String> counterCategoryList = new List<String>();
foreach( PerformanceCounterCategory performanceCounterCategory in PerformanceCounterCategory.GetCategories() )
counterCategoryList.Add( performanceCounterCategory.CategoryName );
counterCategoryList.Sort( delegate( String l, String r ){ return l.CompareTo( r ); } );
return counterCategoryList;
}
public CounterCategory getCategoryCounters( String categoryName )
{
foreach( PerformanceCounterCategory performanceCounterCategory in PerformanceCounterCategory.GetCategories() )
{
if( !performanceCounterCategory.CategoryName.Equals( categoryName ) )
continue;
CounterCategory counterCategory = new CounterCategory( performanceCounterCategory );
if( performanceCounterCategory.CategoryType == PerformanceCounterCategoryType.SingleInstance )
{
List<Counter> counters = new List<Counter>();
foreach( PerformanceCounter performanceCounter in performanceCounterCategory.GetCounters() )
counters.Add( new Counter( performanceCounter ) );
counters.Sort( delegate( Counter l, Counter r ) { return l.Name.CompareTo( r.Name ); } );
counterCategory.Counters[ "SingleInstance" ] = counters;
counterCategory.IsMultiInstance = false;
}
else
{
foreach( String instanceName in performanceCounterCategory.GetInstanceNames() )
{
List<Counter> counters = new List<Counter>();
foreach( PerformanceCounter performanceCounter in performanceCounterCategory.GetCounters( instanceName ) )
counters.Add( new Counter( performanceCounter ) );
counters.Sort( delegate( Counter l, Counter r ) { return l.Name.CompareTo( r.Name ); } );
counterCategory.Counters[ instanceName ] = counters;
counterCategory.IsMultiInstance = true;
}
}
return counterCategory;
}
throw new Exception( "category cannot be found - " + categoryName );
}
public String subscribe( String categoryName, String instance, String counterName )
{
IConnection currentConnection = ConnectionHub.getConnectionLocal();
lock( subscribers )
{
if( !subscribers.ContainsKey( currentConnection ) )
subscribers.Add( currentConnection, new Subscription() );
}
String key = categoryName + "." + instance + "." + counterName;
if( !counters.ContainsKey( key ) )
{
PerformanceCounter performanceCounter = null;
foreach( PerformanceCounterCategory performanceCounterCategory in PerformanceCounterCategory.GetCategories() )
{
if( performanceCounterCategory.CategoryName == categoryName )
{
if( performanceCounterCategory.CategoryType == PerformanceCounterCategoryType.MultiInstance
&& !performanceCounterCategory.InstanceExists( instance ) )
throw new Exception( "Invalid instance name" );
if( !performanceCounterCategory.CounterExists( counterName ) )
throw new Exception( "Invalid counter name" );
if( performanceCounterCategory.CategoryType == PerformanceCounterCategoryType.MultiInstance )
performanceCounter = new PerformanceCounter( performanceCounterCategory.CategoryName, counterName, instance );
else
performanceCounter = new PerformanceCounter( performanceCounterCategory.CategoryName, counterName );
break;
}
}
if( performanceCounter == null )
throw new Exception( "Invalid category name" );
lock( counters )
{
counters.Add( key, performanceCounter );
}
}
lock( subscribers )
{
if( !subscribers[ currentConnection ].Counters.Contains( key ) )
subscribers[ currentConnection ].Counters.Add( key );
}
return key;
}
public String unsubscribe( String key )
{
IConnection currentConnection = ConnectionHub.getConnectionLocal();
if( !subscribers.ContainsKey( currentConnection ) )
return String.Empty;
lock( subscribers )
{
subscribers[ currentConnection ].Counters.Remove( key );
}
return key;
}
public void changeFrequence( int ms )
{
IConnection currentConnection = ConnectionHub.getConnectionLocal();
lock( subscribers )
{
if( !subscribers.ContainsKey( currentConnection ) )
subscribers.Add( currentConnection, new Subscription() );
}
subscribers[ currentConnection ].UpdateFrequency = ms;
subscribers[ currentConnection ].NextEventTime = DateTime.Now.AddMilliseconds( ms );
}
#region IPendingServiceCallback Members
public void resultReceived( IPendingServiceCall call )
{
}
#endregion
}
}