It is not necessary to use variable parameters to write logs, but it is not conducive to encapsulation and the code is ugly. Today I have studied variable parameters.
First view the manual: http://www.cplusplus.com/reference/cstdio/vsprintf? KW = vsprintf
Function <cstdio> vsprintf
int vsprintf (char * s, const char * format, va_list arg );
Write formatted data from variable argument list to string
Composes a string with the same text that wocould be printed ifFormatWas used on printf, but using the elements in the variable argument list identified
ByARGInstead of additional function arguments and storing the resulting content asC stringIn the buffer pointedS.
Internally, the function retrieves arguments from the list identifiedARGAs if va_arg was used on it, and thus the StateARGIs likely
Be altered by the call.
In any case,ARGShocould have been initialized by va_start at some point before the call, and it is expected to be released by va_end
Some point after the call.
Parameters
-
S
-
Pointer to a buffer where the resulting C-string is stored.
The buffer shoshould be large enough to contain the resulting string.
-
Format
-
C string that contains a format string that follows the same specifications
FormatIn printf (see printf
Details ).
-
ARG
-
A value identifying a variable arguments list initialized with va_start.
Va_list is a special type defined in <cstdarg>.
Return Value
On success, the total number of characters written is returned.
On failure, a negative number is returned.
Example
1234567891011121314151617181920212223242526272829
|
/* vsprintf example */#include <stdio.h>#include <stdarg.h>void PrintFError ( const char * format, ... ){ char buffer[256]; va_list args; va_start (args, format); vsprintf (buffer,format, args); perror (buffer); va_end (args);}int main (){ FILE * pFile; char szFileName[]="myfile.txt"; pFile = fopen (szFileName,"r"); if (pFile == NULL) PrintFError ("Error opening '%s'",szFileName); else { // file successfully open fclose (pFile); } return 0;}
|
In this example, if the fileMyfile.txtDoes not exist, perror is called to show an error message similar:
Error opening file 'myfile.txt': No such file or directory |
In summary, the parameter list includes... va_list and so on for Variable Parameter definitions. Va_list requires the header file <stdarg. h>. The va_start (ARGs, format) in the above Code; that is, it is used as a variable parameter from fromat. Vsprintf (buffer, format, argS); that is, convert the variable parameters after the format to the normal string buffer. The above Code directly printf ("% s", buffer); the error opening is obtained.
File "myfile.txt". This is common. Then, in the main function call, add the variables to be added in a way similar to printf. For example, you need to add two int parameters to function ("% d", a, B), and so on. Variable strings are easy to use. What is the principle behind it? See http://renjwjx.blog.51cto.com/811549/243827 is not difficult to understand .. Note: log classes can be used anywhere. The program that records CPU information runs in vs2005 (or later versions). Because vc6.0 does not support psapi. H well, it can obtain CPU information, but cannot obtain memory and transmit data information. In addition, Windows SDK is required to use psapi. If psapi. H is not found during running, you need to install the Windows SDK.
1. psapi. H is required. Install the Windows SDK. After the installation is complete, some things are still unavailable. This is because the SDK does not support vc6.0. And then use vs2005.
2. Set the SDK environment. Set the psapi. h and psapi. Lib paths in the include and Lib directories respectively. For example: (vs2005) the path can be run through
Of course, you can also manually add the configuration. The effect is as follows:
You also need to add dependencies, or directly # pragma
Comment (Lib, "psapi. lib ")
Next, write my log class:
//mylog.h#ifndef MYLOG_H#define MYLOG_H#include <time.h>#include <stdio.h>#include <stdarg.h>class Mylog_{public:Mylog_::Mylog_(const char * logname) {logname_ = logname;FILE *fp = NULL; fp = fopen(logname_, "a+");fclose(fp);}Mylog_::~Mylog_(){if(fp != NULL)fclose(fp);}void Mylog_::writeLogTime(){fp = fopen(logname_, "a+");time(&rawtime);p = localtime(&rawtime);fprintf(fp, "%d/%d/%d ", 1900 + p->tm_year, 1 + p->tm_mon, p->tm_mday);fprintf(fp, "%d:%d:%d", p->tm_hour, p->tm_min, p->tm_sec);fclose(fp);}void Mylog_::recordMessage ( const char * format, ... ){char buffer[256];va_list args;va_start (args, format);vsprintf (buffer,format, args);fp = fopen(logname_, "a+");fprintf(fp, "%s\n", buffer);fclose(fp);va_end (args);}public:const char * logname_;time_t rawtime;tm *p;FILE * fp;};#endif
To obtain the CPU and memory information, you also need:
//process_stat.h#ifndef PROCESS_STAT_H#define PROCESS_STAT_H#include <windows.h>typedef LONG64 int64_t;typedef ULONG64 uint64_t;int get_cpu_usage(int pid);int get_memory_usage(int pid, uint64_t* mem, uint64_t* vmem);int get_io_bytes(int pid, uint64_t* read_bytes, uint64_t* write_byte);int GetPidFromName(LPCSTR lpProcessName);#endif
// The Code comes from: the http://www.rosoo.net/a/201112/15557.html on this basis to modify // process_stat_win.cpp # include <windows. h> # include <psapi. h> # include <assert. h> # include "process_stat.h" # include "process. H "# include" tlhelp32.h "# include <string> using namespace STD; // # DEFINE _ win32_winnt 0x0501 # pragma comment (Lib," psapi. lib ") Static uint64_t file_time_2_utc (const filetime * ftime) {large_integer Li; Assert (ftime); Li. lowpart = f Time-> dwlowdatetime; Li. highpart = ftime-> dwhighdatetime; return Li. quadpart;} static int get_processor_number () {system_info Info; getsysteminfo (& info); Return (INT) info. vertex;} int get_cpu_usage (int pid) {static int processor_count _ =-1; static int64_t last_time _ = 0; static int64_t last_system_time _ = 0; filetime now; filetime creation_time; filetime exit_time; filetime kernel_time; filetime u Ser_time; int64_t system_time; int64_t time; int64_t system_time_delta; int64_t time_delta; int CPU =-1; if (processor_count _ =-1) {processor_count _ = minute ();} getsystemtimeasfiletime (& now); handle hprocess = OpenProcess (process_all_access, false, pid); // in the original version, hprocess is getcurrentprocess () if (! Getprocesstimes (hprocess, & creation_time, & exit_time, & kernel_time, & user_time) {return-1;} system_time = (bytes (& kernel_time) + file_time_2_utc (& user_time )) /processor_count _; time = file_time_2_utc (& now); If (last_system_time _ = 0) | last_time _ = 0) {last_system_time _ = system_time; last_time _ = time; return-1;} system_time_delta = system_time-last_system_time _; time_delta = Time-last_ti Me _; Assert (time_delta! = 0); If (time_delta = 0) Return-1; CPU = (INT) (system_time_delta * 100 + time_delta/2)/time_delta); last_system_time _ = system_time; last_time _ = time; return CPU;} int get_memory_usage (int pid, uint64_t * MEM, uint64_t * vmem) {javaspmc; handle hprocess = OpenProcess (process_all_access, false, pid ); if (getprocessmemoryinfo (hprocess, & PMC, sizeof (PMC) {If (MEM) * mem = PMC. workingsets Ize; If (vmem) * vmem = PMC. pagefileusage; return 0;} return-1;} int evaluate (int pid, uint64_t * read_bytes, uint64_t * write_byte) {io_counters io_counter; handle hprocess = OpenProcess (process_all_access, false, PID); If (getprocessiocounters (hprocess, & io_counter) {If (read_bytes) * read_bytes = io_counter.readtransfercount; If (write_byte) * write_byte = cursor; return 0;} return-1; }/* Void restartprocess (cstring proname) {bool iskill = killprocessfromname (proname); If (iskill) printf ("kill % s success \ n", proname. getbuffer (0); elseprintf ("kill % s failed \ n", proname. getbuffer (0); cstring strpath1; strpath1 = proname; sleep (1000); createnewprocess (strpath1); sleep (5000); int I = 1; while (findprocessfromname (proname) ==false & I <3) {I ++; createnewprocess (strpath1); sleep (5000) ;}} bool cr Eatenewprocess (lpcstr pszexename) {process_information piprocinfogps; startupinfo sistartupinfo; using saprocess, sathread; zeromemory (& sistartupinfo, sizeof (sistartupinfo); sistartupinfo. CB = sizeof (sistartupinfo); saprocess. nlength = sizeof (saprocess); saprocess. lpsecuritydescriptor = NULL; saprocess. binherithandle = true; sathread. nlength = sizeof (sathread); sathread. lpsecuritydescriptor = NULL; sathread. binherithandle = true; Return: CreateProcess (null, (lptstr) pszexename, & saprocess, & sathread, false, create_default_error_mode, null, null, & sistartupinfo, & piprocinfogps );} bool findprocessfromname (lpcstr lpprocessname) {handle hsnapshot = createconlhelp32snapshot (th32cs_snapprocess, 0); processentry32 PE; PE. dwsize = sizeof (processentry32); If (! Process32first (hsnapshot, & PE) {return false;} cstring strprocessname = lpprocessname; strprocessname. makelower (); While (process32next (hsnapshot, & PE) {cstring sctmp = PE. szexefile; sctmp. makelower (); If (! Sctmp. compare (strprocessname) {return true;} sctmp. releasebuffer ();} strprocessname. releasebuffer (); Return false;} bool killprocessfromname (lpcstr lpprocessname) {handle hsnapshot = createconlhelp32snapshot (th32cs_snapprocess, 0); processentry32 PE; PE. dwsize = sizeof (processentry32); If (! Process32first (hsnapshot, & PE) {return false;} cstring strprocessname = lpprocessname; strprocessname. makelower (); While (process32next (hsnapshot, & PE) {cstring sctmp = PE. szexefile; sctmp. makelower (); If (! Sctmp. compare (strprocessname) {DWORD dwprocessid = PE. th32processid; // obtain pidhandle hprocess =: OpenProcess (process_terminate, false, dwprocessid); // no matter whether the PID or process name is used, the Process Handle is obtained: terminateprocess (hprocess, 0); closehandle (hprocess); Return true;} sctmp. releasebuffer ();} strprocessname. releasebuffer (); Return false;} */INT getpidfromname (lpcstr lpprocessname) {handle hsnapshot = createconlhelp32snaps Hot (th32cs_snapprocess, 0); processentry32 PE; PE. dwsize = sizeof (processentry32); If (! Process32first (hsnapshot, & PE) {return false;} // cstring strprocessname = lpprocessname; string strprocessname (lpprocessname); // strprocessname. makelower (); While (process32next (hsnapshot, & PE) {// required here // cstring sctmp = PE. szexefile; char buffer [260]; wcstombs (buffer, PE. szexefile, sizeof (buffer); string sctmp (buffer); // sctmp. makelower (); If (! Sctmp. Compare (strprocessname) {DWORD dwprocessid = PE. th32processid; // obtain pidreturn dwprocessid;} return-1 ;}
// Main. CPP # include "process_stat.h" # include <windows. h> # include <stdio. h> # include "mylog. H "const char processname [] =" platesvr.exe "; const char LOGNAME [] =" log1.txt "; int main () {int pid =-1; pid = getpidfromname (processname ); if (pid =-1) {printf ("cann' t find the process. please confirm the processname \ n "); Return 0;} printf (" processname = % s pid = % d \ n ", processname, pid ); printf ("logging to % s", LOGNAME); W Hile (1) {int CPU; uint64_t MEM, vmem, R, W; CPU = get_cpu_usage (PID); get_memory_usage (PID, & MEM, & vmem); get_io_bytes (PID, & R, & W); // It is useless in this program and useful elsewhere .. Mylog _ log (LOGNAME); log. writelogtime (); log. recordmessage ("CPU: % d % memory: % u KB \ n", CPU, MEM/1000); sleep (1000); // record interval} return 0 ;}
These things can be run together. If they cannot be run, it may be caused by a problem in the environment. Running effect: