单纯的写日志,没必要使用可变参数,但是不利于封装,代码难看,今天研究了一下可变参数
先查看手册:http://www.cplusplus.com/reference/cstdio/vsprintf/?kw=vsprintf
vsprintf
int vsprintf (char * s, const char * format, va_list arg );
Composes a string with the same text that would be printed if format was used on printf, but using the elements in the variable argument list identified
by arg instead of additional function arguments and storing the resulting content as a C string in the buffer pointed by s.
Internally, the function retrieves arguments from the list identified by arg as if va_arg was used on it, and thus the state of arg is likely to
be altered by the call.
In any case, arg should have been initialized by va_start at some point before the call, and it is expected to be released by va_end at
some point after the call.
Parameters
- s
- Pointer to a buffer where the resulting C-string is stored.
The buffer should be large enough to contain the resulting string. - format
- C string that contains a format string that follows the same specifications as format in printf (see printf for
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
|
|
In this example, if the file myfile.txt does not exist, perror is called to show an error message similar to:
Error opening file 'myfile.txt': No such file or directory |
file "myfile.txt". 很常规。
1. 需要psapi.h 。 需要安装windows sdk。 安装完了之后发现,有的东西还是不能用。是因为sdk对vc6.0的支持不够。后改用vs2005后解决。
2. sdk 环境的设置。 在include 和lib 目录里面分别设置psapi.h 和psapi.lib的路径。比如:(vs2005)的路径可以通过运行
的最后一个configuration 进行设置,当然也可以手工加入,效果如下:
还需要添加附加依赖项,或者直接#pragma
comment(lib, "Psapi.lib")
//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
//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
//代码源自:http://www.rosoo.net/a/201112/15557.html 在此基础上进行修改 //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 = ftime->dwLowDateTime; li.HighPart = ftime->dwHighDateTime; return li.QuadPart; } static int get_processor_number() { SYSTEM_INFO info; GetSystemInfo(&info); return (int)info.dwNumberOfProcessors; } 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 user_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_ = get_processor_number(); } GetSystemTimeAsFileTime(&now); HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, pid); //原来版本中,hProcess 为 GetCurrentProcess() if(!GetProcessTimes(hProcess, &creation_time,&exit_time, &kernel_time, &user_time)) { return -1; } system_time = (file_time_2_utc(&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_time_; 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) { PROCESS_MEMORY_COUNTERS pmc; HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, pid); if(GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc))) { if(mem) *mem = pmc.WorkingSetSize; if(vmem) *vmem = pmc.PagefileUsage; return 0; } return -1; } int get_io_bytes(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 = io_counter.WriteTransferCount; return 0; } return -1; } /*void ReStartProcess(CString proname) { bool isKill = KillProcessFromName(proname); if(isKill) printf("kill %s success\n", proname.GetBuffer(0)); else printf("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 CreateNewProcess(LPCSTR pszExeName) { PROCESS_INFORMATION piProcInfoGPS; STARTUPINFO siStartupInfo; SECURITY_ATTRIBUTES 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 = CreateToolhelp32Snapshot(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 = CreateToolhelp32Snapshot(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; //获得pid HANDLE hProcess = ::OpenProcess(PROCESS_TERMINATE,FALSE,dwProcessID); //不管通过pid还是进程名字最终都是为了获得进程的句柄 ::TerminateProcess(hProcess,0); CloseHandle(hProcess); return TRUE; } scTmp.ReleaseBuffer(); } strProcessName.ReleaseBuffer(); return FALSE; }*/ int GetPidFromName(LPCSTR lpProcessName) { HANDLE hSnapShot = CreateToolhelp32Snapshot(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)) { //这里需要 //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; //获得pid return 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("正在记录到%s", logName); while(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); //在本程序中没用,在别的地方有用。。 Mylog_ log(logName); log.writeLogTime(); log.recordMessage("cpu: %d%% 内存:%u KB\n", cpu, mem/1000); Sleep(1000); //记录间隔 } return 0; }
这些东西放在一起,应该是可以运行的,如果不能运行,有可能是环境出了什么问题。