This is a time to do a project about data interaction. After receiving the files sent by the customer, the files are distributed to different MQ message queues by the Windows service and then processed by different handlers. Although in the code as far as possible to consider the exception and log the detailed logs, but the service is occasional convulsions stopped, which caused the accumulation of files, customer requests are not timely response. Therefore, a daemon is required to ensure that the service is always in the boot state.
First, make sure that the processes you need to monitor are configurable, and specify where the logs will be saved. Configure the log save path in App. config and the location where you want to monitor the process and the corresponding EXE executable (before considering if the service is not available, use the EXE installation service).
< appSettings > < key= "LogPath" value= "D:\Study"/> < Key = "ytgdataexchangeprocess" value= "d:\Study\ YTGDataExchangeProcess.exe "/> </appSettings>
Public classServicesearch {StaticList<serviceprocessinfo> _servicelist =NewList<serviceprocessinfo>(); Static Object_loglocker =NewObject (); //Log Record Location Static ReadOnly string_logpath; StaticServicesearch () {Try { string[] Appsettingskeys =ConfigurationManager.AppSettings.AllKeys; foreach(stringIteminchAppsettingskeys) { stringValue =Configurationmanager.appsettings[item]. Trim (); //Log Configuration if(Item = ="LogPath") { if(!string. IsNullOrEmpty (value)) {_logpath=string. Format ("{0}\\processmonitorlog", value); if(!directory.exists (_logpath)) {directory.createdirectory (_logpath); } } } Else { if(!string. IsNullOrEmpty (value)) {//whether the application exists if(file.exists (value)) {_servicelist.add (NewServiceprocessinfo {Serviceexepath=value, ServiceName=item}); } } } } } Catch(Exception ex) {Writelog (ex). Message); } } Public Static voidStartMonitor () {if(_servicelist.count! =0) { foreach(Serviceprocessinfo Infoinch_servicelist) { stringSevname =info. ServiceName; stringSevexepath =info. Serviceexepath; if(!string. IsNullOrEmpty (Sevexepath)) {//Verify EXE file exists if(File.exists (Sevexepath)) {Scanservicemanager (Sevname, Sevexepath) ; } } } } Else{Writelog ("There are no services configured to monitor! "); } } /// <summary> ///find a process for a service///If the process is running, the non-running state starts/// </summary> Public Static voidScanservicemanager (stringServiceName,stringServiceexepath) { Try{ServiceController Sevctrler=NewServiceController (serviceName); //the service already exists//If the service status is not started if(Sevctrler.status! =servicecontrollerstatus.running) {Sevctrler.start (); } //Creating a monitoring threadWatchservice (serviceName); } Catch(Exception ex) {//The service does not existWritelog (string. Format (ex. Message)); } } /// <summary> ///to add a monitoring process to a configured process/// </summary> /// <param name= "Pro" ></param> /// <param name= "processaddress" ></param> Public Static voidWatchservice (stringServiceName) {Servicemonitor Monitor=NewServicemonitor (ServiceName); Thread Thread=NewThread (NewThreadStart (monitor. Monitor)); Thread. IsBackground=true; Thread. Start (); } /// <summary> ///Write Log/// </summary> /// <param name= "Errmessage" ></param> Public Static voidWritelog (stringerrmessage) { stringLogPath =_logpath; //No log directory configured, no logging if(!string. IsNullOrEmpty (LogPath)) {Lock(_loglocker) {stringFullName =string. Format ("{0}\\{1}.log", LogPath, DateTime.Now.ToString ("YYYY-MM-DD")); if(!file.exists (FullName)) {file.create (fullName). Close (); } using(StreamWriter SW =NewStreamWriter (FullName,true, Encoding.UTF8)) {SW. WriteLine (String.Format ("[{0}]{1}", DateTime.Now.ToString ("Hh:mm:ss FFF") , errmessage)); Sw. Close (); } } } } Public classServiceprocessinfo {/// <summary> ///Service Name/// </summary> Public stringServiceName {Get; Set; } /// <summary> ///Application Location/// </summary> Public stringServiceexepath {Get; Set; } } }
In the Scanservicemanager method above, the ServiceController object is instantiated with servicename and a separate thread is enabled to poll it to monitor its state, otherwise it will only block after the first service is monitored.
Public classServicemonitor {/// <summary> ///Service Name/// </summary> Private string_servicename; Public stringServiceName {Get{return_servicename;} Set{_servicename =value;} } PublicServicemonitor (stringServiceName) { This. _servicename =ServiceName; } /// <summary> ///Monitoring Services/// </summary> Public voidMonitor () { while(true) { Try{ServiceController Ctrler=NewServiceController (_servicename); if(Ctrler. Status! =servicecontrollerstatus.running) {Servicesearch.writelog (string. Format ("starting service {0} ...", _servicename)); Ctrler. Start (); Servicesearch.writelog (string. Format ("Service {0} started successfully! ", _servicename)); } } Catch(Exception ex) {Servicesearch.writelog (string. Format ("Service {0} failed to start, error reason: {1}", _servicename, ex. Message)); } thread.sleep ( +* +); } } }
The daemons implemented by C #