单纯的写日志,没必要使用可变参数,但是不利于封装,代码难看,今天研究了一下可变参数
先查看手册:http://www.cplusplus.com/reference/cstdio/vsprintf/?kw=vsprintf
int vsprintf (char * s, const char * format, va_list arg );
|
|
Error opening file 'myfile.txt': No such file or directory |
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; }