Browse Source

Z991239-351 #comment 1.添加一个实体;2.WLog根据日期文件名输出;添加框架错误码;TODO:logSubScribe崩掉

gifur 5 years ago
parent
commit
b4e275cacc

+ 26 - 32
Common/ErrorCode.h

@@ -21,31 +21,34 @@ enum ErrorCodeEnum
 	Error_TargetBeing=0x200,		
 	Error_NoTarget,				//request target is not exist
 	Error_NoDefine,				//The class or object no define
-	Error_NotImpl,				//the method has not implement yet
-	Error_NotExist,				//not exist
+	Error_NotImpl,				    //the method has not implement yet
+	Error_NotExist,				    //not exist
 	Error_Duplication,			//Duplicate action or object
-	Error_Unregisted,			//exist but the object has not registered
+	Error_Unregisted,			    //exist but the object has not registered
 	Error_AlreadyExist,			//already exist
 	Error_MethodNotFound,		//method does not exist
-	Error_Redirect,				// redirect indication
-	Error_BridgeNotBind,	// bridge bind indication
-	Error_BridgeNotOK,		// try bridge fail
+	Error_Redirect,				    // redirect indication
+	Error_BridgeNotBind,	    // bridge bind indication
+	Error_BridgeNotOK,		    // try bridge fail
+	Error_NotSupport,          // don't support the request
 
 	//Entity state's category
 	Error_InvalidState=0x300,	//state is not valid for current call
-	Error_NotInit,				//The target is not be initial
-	Error_Paused,				//the access object is in Pause state
-	Error_Stoped,				//the access object is in Stop state
-	Error_Losted,				//the access object is in Lost state 
-	Error_Closed,				//opposite side in close state
+	Error_NotInit,				   //The target is not be initial
+	Error_Paused,				   //the access object is in Pause state
+	Error_Stoped,				   //the access object is in Stop state
+	Error_Losted,				   //the access object is in Lost state 
+	Error_Closed,				  //opposite side in close state
+	Error_Accept,                 //test mode: pass the test
+	Error_Failed,                  //test mode: fail to pass the test.
 
 	//Framework Task control's category
 	Error_TaskControl=0x400,
 	Error_Pending,				//The request in not finish
 	Error_Cancel,				//The process is be cancel by framework
-	Error_Break,				//The task has interrupt
-	Error_NotMeetCondition,		//not meat run condition,run cancel
-	Error_NoPrivilege,			//no privilege
+	Error_Break,				    //The task has interrupt
+	Error_NotMeetCondition,		 //not meat run condition,run cancel
+	Error_NoPrivilege,			         //no privilege
 	Error_MethodSignatureFailed,//method signature failed
 
 	//opposite side action's category 
@@ -57,10 +60,10 @@ enum ErrorCodeEnum
 
 	//process fail's category
 	Error_Process=0x600,
-	Error_NetBroken,			//the network is broken
+	Error_NetBroken,			    //the network is broken
 	Error_UpdateFailed,			//system update failed
 	Error_RegistryFailed,		//registry operation failed
-	Error_IO,					//IO error(file reading/writing)
+	Error_IO,					        //IO error(file reading/writing)
 	Error_Readonly,				//The object can't be edit
 
 	Error_TimeOut=0x700,
@@ -70,31 +73,22 @@ enum ErrorCodeEnum
 	Error_ReplyTimeOut,			//The system max answer time
 
 	Error_Hardware=0x800,
-	Error_DevLoadFileFailed,	//load dll or config file failed
+	Error_DevLoadFileFailed,   	//load dll or config file failed
 	Error_DevNotAvailable,		//device not connected
 	Error_DevAlreadyConnected,	//device already connected
-	Error_DevConnFailed,		//connect to device failed
+	Error_DevConnFailed,		    //connect to device failed
 	Error_DevCommFailed,		//Communication failed between HOST and Device
-	Error_DevMedia,				//Media error(Data lack,unrecognized and so on)
-	Error_EnvCamera,			//EnvCamera error
-	Error_OptCamera,			//OptCamera error(Data lack,unrecognized and so on)
-	Error_AllCamera,			//AllCamera error(Data lack,unrecognized and so on)
-	//Error_Audio,
+	Error_DevMedia,				    //Media error(Data lack,unrecognized and so on)
+	Error_EnvCamera,			    //EnvCamera error
+	Error_OptCamera,			    //OptCamera error(Data lack,unrecognized and so on)
+	Error_AllCamera,			        //AllCamera error(Data lack,unrecognized and so on)
 	Error_AudioIN,
 	Error_AudioOut,
 	
 	Error_Debug=0xf00,
 	Error_Assert,
 	Error_Trace,
-	Error_Bug,					//bug detected
-	
-	/*
-	// device error code x define at range 0x00010000 <= x <= 0x0001ffff
-	// 
-	Error_Device_Begin = 0x00010000, 
-	//...... device error codes goes here
-	Error_Device_End = 0x0001ffff,
-	*/
+	Error_Bug,					       //bug detected
 
 	Error_Unrecover=0x70000000,
 	Error_Resource,				//The system resource ec:memory/handle/space,do not retry,should restart system

+ 4 - 2
Common/SpBase.h

@@ -106,6 +106,8 @@ enum EntityStateEnum
 	EntityState_Lost,				//Entity block not respond or exception
 	EntityState_Close,				//After close,start before
 	EntityState_Killed,				//The entity terminated as block state
+	EntityState_Passed,         //The entity pass all test case
+	EntityState_Failed           // The entity fail to pass the test case.
 };
 
 enum EntityCloseCauseEnum
@@ -288,8 +290,8 @@ public:
 	inline bool operator >(const CUUID &UUID){return m_nUUID64>UUID.m_nUUID64;}
 	inline bool operator <=(const CUUID &UUID){return m_nUUID64<=UUID.m_nUUID64;}
 	inline bool operator >=(const CUUID &UUID){return m_nUUID64>=UUID.m_nUUID64;}
-	inline DWORD GetAppID(){return m_nAppID;}
-	inline CSimpleStringA ToString() { return CSimpleStringA::Format("%016llX", m_nUUID64); }
+	inline DWORD GetAppID() const {return m_nAppID;}
+	inline CSimpleStringA ToString() const { return CSimpleStringA::Format("%016llX", m_nUUID64); }
 	static CUUID Create(const CUUID &LastUUID);
 };
 

+ 4 - 4
addin/cfg/shell.ini.in

@@ -5,14 +5,14 @@ SoftwareVersion=@RVC_FRAMEWORK_VERSION@
 HelloService=0,@LIB_PREFIX@mod_helloservice@LIB_SUFFIX@,0x101
 HelloClient=0,@LIB_PREFIX@mod_helloclient@LIB_SUFFIX@,0x102
 SampleEntity=0,@LIB_PREFIX@mod_SampleEntity@LIB_SUFFIX@,0x103
-
+LogSubscribe=0,@LIB_PREFIX@mod_logSubscribe@LIB_SUFFIX@,0x104
+BlackSheep=0,@LIB_PREFIX@mod_blackSheep@LIB_SUFFIX@,0x105
 [Startup]
-Number=3
+Number=4
 1=HelloService
 2=HelloClient
 3=SampleEntity
-
-
+4=LogSubscribe
 
 [Debug]
 HelloClient=1

+ 33 - 3
doc/tutorials/entity_dev.md

@@ -6,12 +6,42 @@
 
 实体需要继承 `CEntityBase`并实现`OnNewSession`接口,该函数返回一个会话对象,在对方第一个连接过来时会调用该函数返回一个实际的会话对象。**前提是`IsService()`必须返回 true**
 
-## 实体接口执行流程
+## 接口执行流程
 
-1. ``
-2. `void OnSarted()` *(SpEntity::FinishStart)*
+### 实体
 
+1. 启动前
 
+```c++
+void OnPreStart(CAutoArray<CSimpleStringA> strArgs,CSmartPointer<ITransactionContext> pTransactionContext) 
+{
+    /**/
+    pTransactionContext->SendAnswer(Error_Succeed);
+}
+```
+
+2. 启动后
+
+```c++
+void OnSarted()
+```
+
+### 状态机
+
+1. 初始化
+
+在框架实现中,`Init`接口内部会调用`OnInit`接口
+
+```c++
+ErrorCodeEnum FSMBase::Init(CEntityBase *pEntity)
+{
+	//...
+	ErrorCodeEnum Error = OnInit();
+	//...
+}
+```
+
+所以在实体中初始化状态机对象时,不要直接调用`OnInit`接口,而是通过调用`Init`接口间接触发
 
 ## 实体静态注册宏
 

+ 21 - 11
module/CMakeLists.txt

@@ -49,17 +49,27 @@ endmacro(deploy_module)
 set(MODULE_BASE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
 
 # ±éÀúʵÌå
-file(GLOB module_dirs RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "${CMAKE_CURRENT_SOURCE_DIR}/*")
-set(module_list "")
-foreach(module_dir ${module_dirs})
-    if(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${module_dir})
-        list(APPEND module_list ${module_dir})
-    endif()
-endforeach()
-foreach(module ${module_list})
-    message(STATUS  "add module ${module}...")
-    add_subdirectory(${module})
-endforeach()
+# file(GLOB module_dirs RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "${CMAKE_CURRENT_SOURCE_DIR}/*")
+# set(module_list "")
+# foreach(module_dir ${module_dirs})
+#   if(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${module_dir})
+#        list(APPEND module_list ${module_dir})
+#    endif()
+#endforeach()
+#foreach(module ${module_list})
+#    message(STATUS  "add module ${module}...")
+#    add_subdirectory(${module})
+#endforeach()
+
+file(GLOB all_valid_subdirs RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*/CMakeLists.txt")
+
+foreach(dir ${all_valid_subdirs})
+	if(${dir} MATCHES "^([^/]*)/+CMakeLists.txt")
+		string(REGEX REPLACE "^([^/]*)/+CMakeLists.txt" "\\1" dir_trimmed ${dir})
+		message(STATUS "add module ${dir_trimmed}")
+		add_subdirectory(${dir_trimmed})
+	endif()
+endforeach(dir)
 
 
 

+ 13 - 0
module/mod_blackSheep/CMakeLists.txt

@@ -0,0 +1,13 @@
+# 定义实体名称
+define_moudle("blackSheep")
+
+set(${MODULE_PREFIX}_SRCS
+	mod_blackSheep.cpp)
+
+add_module_libraries(${MODULE_PREFIX} ${MODULE_NAME})
+
+# 添加实体需要依赖的其他共享库(包括系统库)
+set(${MODULE_PREFIX}_LIBS spbase winpr)
+target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
+
+deploy_module(${MODULE_PREFIX} ${MODULE_NAME})

+ 34 - 0
module/mod_blackSheep/mod_blackSheep.cpp

@@ -0,0 +1,34 @@
+#include "stdafx.h"
+#include "SpBase.h"
+
+
+
+class CBlackSheep : public CEntityBase
+{
+public:
+	CBlackSheep() {}
+	virtual ~CBlackSheep() {}
+	virtual const char *GetEntityName() const { return "BlackSheep"; }
+
+
+	virtual void OnPreStart(CAutoArray<CSimpleStringA> strArgs, CSmartPointer<ITransactionContext> pTransactionContext)
+	{
+		LOG_FUNCTION();
+		pTransactionContext->SendAnswer(Error_Unexpect);
+	}
+
+	virtual void OnStarted()
+	{
+		LOG_FUNCTION();
+	}
+
+	virtual void OnPreClose(EntityCloseCauseEnum eCloseCause,CSmartPointer<ITransactionContext> pTransactionContext) 
+	{ 
+		LOG_FUNCTION();
+		pTransactionContext->SendAnswer(Error_Succeed); 
+	}
+};
+
+SP_BEGIN_ENTITY_MAP()
+	SP_ENTITY(CBlackSheep)
+SP_END_ENTITY_MAP()

+ 13 - 0
module/mod_logSubscribe/CMakeLists.txt

@@ -0,0 +1,13 @@
+# 定义实体名称
+define_moudle("logSubscribe")
+
+set(${MODULE_PREFIX}_SRCS
+	mod_logSubscribe.cpp)
+
+add_module_libraries(${MODULE_PREFIX} ${MODULE_NAME})
+
+# 添加实体需要依赖的其他共享库(包括系统库)
+set(${MODULE_PREFIX}_LIBS spbase winpr)
+target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
+
+deploy_module(${MODULE_PREFIX} ${MODULE_NAME})

+ 97 - 0
module/mod_logSubscribe/mod_logSubscribe.cpp

@@ -0,0 +1,97 @@
+#include "stdafx.h"
+#include "SpBase.h"
+
+
+typedef  ULONG LogTypeSeverity[Log_Debug + 1][Severity_High + 1];
+
+
+class CLogSubscribeEntity : public CEntityBase
+	, public ITimerListener
+	, public ISysVarListener
+	, public IBroadcastListener
+	, public ILogListener
+{
+public:
+	CLogSubscribeEntity():m_logCalCount(NULL) {
+		m_logCalCount = new LogTypeSeverity[0x1000];
+	}
+	virtual ~CLogSubscribeEntity() {
+		if (m_logCalCount)
+			delete[] m_logCalCount;
+	}
+	virtual const char *GetEntityName() const { return "logSubscribe"; }
+
+	/*for {ITimerListener} implement*/
+	void OnTimeout(DWORD dwTimerID)
+	{
+		LOG_TRACE("timeout, id: %d", dwTimerID);
+	}
+
+	/*for {ISysVarListener} implement */
+	virtual void OnSysVarEvent(const char *pszKey, const char *pszValue,const char *pszOldValue,const char *pszEntityName)
+	{
+		LOG_TRACE("entity:%s key:%s value:%s, old_value:%s", pszEntityName, pszKey, pszValue, pszOldValue);
+	}
+
+	virtual void OnPreStart(CAutoArray<CSimpleStringA> strArgs, CSmartPointer<ITransactionContext> pTransactionContext)
+	{
+		LOG_FUNCTION();
+		ErrorCodeEnum ec = Error_Succeed;
+		Dbg("to subscribe all entity log.");
+		GetFunction()->SubscribeLog(m_logSubUUID, this, Log_Ignore, Severity_None, Error_IgnoreAll, -2, NULL, false);
+		pTransactionContext->SendAnswer(Error_Succeed);
+	}
+
+	virtual void OnStarted()
+	{
+		LOG_FUNCTION();
+	}
+
+	virtual void OnPreClose(EntityCloseCauseEnum eCloseCause,CSmartPointer<ITransactionContext> pTransactionContext) 
+	{ 
+		LOG_FUNCTION();
+		Dbg("to unsubscribe all entity log.");
+		GetFunction()->UnsubscribeLog(m_logSubUUID);
+		pTransactionContext->SendAnswer(Error_Succeed); 
+	}
+
+	void OnBroadcastEvent(CUUID SubID,
+		const char* pszEntityName,
+		DWORD dwMessageId,
+		DWORD dwMessageSignature,
+		CAutoBuffer Buffer)
+	{
+		Dbg("OnBroadcastEvent: %s, %s, 0x%X, 0x%X, buffer size: %u", (LPCTSTR)SubID.ToString(), pszEntityName,
+			dwMessageId, dwMessageSignature, Buffer.GetCount());
+	}
+
+	void OnLog(const CAutoArray<CUUID>& SubIDs
+		, const CUUID nLogID
+		, const LogTypeEnum eLogType
+		, const SeverityLevelEnum eLevel
+		, const DWORD dwSysError, const DWORD dwUserCode
+		, const DWORD dwEntityInstanceID, const WORD wEntityDevelID
+		, const CAutoArray<DWORD>& Param
+		, const char* pszEntityName, const char* pszModuleName, const char* pszMessage)
+	{
+		if (m_logCalCount) {
+			m_logCalCount[wEntityDevelID][eLogType][eLevel]++;
+		}
+		Dbg("OnLog(%s, %d, %d, 0x%X, 0x%X, 0x%X, 0x%04X, %s, %s, %s",
+			(LPCTSTR)nLogID.ToString(), eLogType, eLevel, dwSysError, dwUserCode,
+			dwEntityInstanceID, wEntityDevelID, pszEntityName, pszModuleName, pszMessage);
+		if (Param.GetCount() > 0) {
+			for (int i = 0; i < Param.GetCount(); ++i) {
+				Dbg("Params[%d]: %d", i, Param[i]);
+			}
+		}
+	}
+
+private:
+	CUUID m_logSubUUID;
+	LogTypeSeverity* m_logCalCount;
+};
+
+SP_BEGIN_ENTITY_MAP()
+	SP_ENTITY(CLogSubscribeEntity)
+SP_END_ENTITY_MAP()

+ 40 - 6
module/mod_sample/SampleFSM.cpp

@@ -6,6 +6,9 @@
 #include "stdafx.h"
 #include "SampleFSM.h"
 
+#define TIMER_LOG_SEND_ID 1
+#define TIMER_LOG_SEND_INTERVAL 6000
+
 CSampleFSM::CSampleFSM(void)
 {
 	// TODO:
@@ -16,14 +19,18 @@ CSampleFSM::~CSampleFSM(void)
 	// TODO:
 }
 
+/*When invoke the {Init} interface of FSM instance, this function would fire immediately.
+* The user should not invoke this function directly.
+*/
 ErrorCodeEnum CSampleFSM::OnInit()
 {
 	LOG_FUNCTION();
-	//MessageBox(NULL, NULL, NULL, 0);
 	ErrorCodeEnum ec = Error_Unexpect;
 
 	// TODO: user should implement the function!
 
+	ec = Error_Succeed;
+
 	return ec;
 }
 
@@ -45,20 +52,47 @@ void CSampleFSM::SelfTest(EntityTestEnum eTestType,CSmartPointer<ITransactionCon
 
 void CSampleFSM::s0_on_entry()
 {
-	// TODO:
+	ScheduleTimer(TIMER_LOG_SEND_ID, TIMER_LOG_SEND_INTERVAL);
 }
 
 void CSampleFSM::s0_on_exit()
 {
-	// TODO:
+	CancelTimer(TIMER_LOG_SEND_ID);
 }
 
 unsigned int CSampleFSM::s0_on_event(FSMEvent* e)
 {
 	unsigned int uRet = 0;
-
-	// TODO:
-
+	static ULONG ulCalcuTimes = 0;
+	if (e->iEvt == EVT_TIMER) {
+		LOG_ASSERT(e->param1 == 1);
+		const auto delim = ulCalcuTimes % 3;
+		const DWORD dwUserCode = ((DWORD)ENTITY_DEV_ID << 20 | (DWORD)(ulCalcuTimes & 0x000FFFFF));
+		for (SeverityLevelEnum severity = Severity_None; severity <= Severity_High; severity = (SeverityLevelEnum)(severity + 1)) {
+			if (delim == 0) {
+				LogEvent(severity, dwUserCode, CSimpleStringA::Format("event log from %s, current times: %ul", GetEntityBase()->GetEntityName(), ulCalcuTimes));
+			}
+			else if (delim == 1) {
+				LogWarn(severity, Error_Duplication, dwUserCode, CSimpleStringA::Format("warn log from %s, current times: %ul", GetEntityBase()->GetEntityName(), ulCalcuTimes));
+			}
+			else if (delim == 2) {
+				LogError(severity, Error_Duplication, dwUserCode, CSimpleStringA::Format("error log from %s, current times: %ul", GetEntityBase()->GetEntityName(), ulCalcuTimes));
+			}
+			CAutoArray<DWORD> sendParams;
+			sendParams.Init(3);
+			sendParams[0] = (DWORD)severity;
+			for (LogTypeEnum logType = Log_Ignore; logType <= Log_Debug; logType = (LogTypeEnum)(logType + 1)) {
+				sendParams[1] = (DWORD)logType;
+				sendParams[2] = dwUserCode;
+				GetEntityBase()->GetFunction()->SendLog(logType, severity, dwUserCode, sendParams, 
+					CSimpleStringA::Format("send log from %s, current times: %ul", GetEntityBase()->GetEntityName(), ulCalcuTimes));
+			}
+		}
+		LOG_TRACE("////////////////////////////////////////////////////////////////////////////////////////////////");
+		++ulCalcuTimes;
+		
+		ScheduleTimer(TIMER_LOG_SEND_ID, TIMER_LOG_SEND_INTERVAL);
+	}
 	return uRet;
 }
 

+ 2 - 0
module/mod_sample/SampleFSM.h

@@ -11,6 +11,8 @@
 
 using namespace SampleEntity;
 
+#define ENTITY_DEV_ID 0x103
+
 //
 // fsm event enum goes here
 //

+ 2 - 1
spbase/SpBase.cpp

@@ -317,11 +317,12 @@ extern "C" SPBASE_API int __stdcall SpRun(const char *mod_name, int epid, int ra
 	}
 #endif //_WIN32
 
+	sp_dbg_init(mod_name);
+
 	if (winsock_init() != 0) {
 		return Error_NetBroken;
 	}
 
-	sp_dbg_init(mod_name);
 	sp_dbg_info("==============SpRun(%s) start==============", mod_name);
 	sp_dbg_info("process id: %d", GetCurrentProcessId());
 	

+ 1 - 1
spbase/SpEntity.cpp

@@ -1355,7 +1355,7 @@ ErrorCodeEnum SpEntity::GetRebootInfo(CSmallDateTime BeforeThisTime, CBootInfo &
 	if (rc != Error_Succeed)
 		return rc;
 
-	strPath += "\\BootLog";
+	strPath += SPLIT_SLASH_STR "BootLog";
 	sp_env_t *env = sp_get_env();
 	auto pRec = sp_btr_get_rec_before(strPath, env->btr_ctx, BeforeThisTime);
 	if (pRec == NULL)

+ 10 - 15
sphost/sphost.c

@@ -30,11 +30,8 @@ HANDLE threadRunLock;
 
 // sphost.exe <mod_name> <epid> <hint_addr>
 
-
-int __declspec(dllimport) __stdcall SpRun(const char *mod_name, int epid, int range, int group);
-#ifdef _WIN32
-int __declspec(dllimport) __stdcall SpExit(const char* mod_name);
-#endif //_WIN32
+int SPBASE_API __stdcall SpRun(const char* mod_name, int epid, int range, int group);
+int SPBASE_API __stdcall SpExit(const char* mod_name);
 
 static void SetEnvPath(const char *mod_name)
 {
@@ -78,22 +75,15 @@ static void SetEnvPath(const char *mod_name)
 		strcat(buf, path);
 		SetEnvironmentVariableA(var, buf);
 	}
-
 	free(buf);
+
+	SetEnvironmentVariableA("ModuleName", mod_name);
 }
 
 #ifdef _WIN32
 
 DWORD sphostMonitor(LPVOID param)
 {
-// 	HANDLE spShellProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetProcessIdFromName(PROCESS_SPSHELL));	//»ñÈ¡µÄÊÇ׼ȷµÄspshell.exeµÄpid
-// 	int waitTimes = 1;
-// 	if (NULL == spShellProcess)
-// 	{
-// 		CloseHandle(spShellProcess);
-// 		ExitProcess(-1);	//can not find spShell
-// 	}
-		
 	int waitTimes = 1;
 	while (0 != GetProcessIdFromName(PROCESS_SPSHELL))	//spshell exit
 	{
@@ -244,7 +234,6 @@ int main(int argc, char *argv[])
 	if (!SetNamedPipeHandleState(hPipe, &dwMode, NULL, NULL))
 		return -1;
 
-
 	hMutex = OpenEvent(EVENT_ALL_ACCESS, FALSE, argv[1]);
 	SetEvent(hMutex);
 	CloseHandle(hMutex);
@@ -269,6 +258,9 @@ int main(int argc, char *argv[])
 			curModInfo->range = atoi(dstParam[3]);
 			strcpy(curModInfo->modMutexName, dstParam[4]);
 			curModInfo->group = atoi((dstParam[5]));
+
+			WLog_initRVC(curModInfo->mod_name);
+
 			/*TODO: can use Dbg before SpRun invoke bcz dbg init inner.*/
 			Dbg("query Entity %s start, epid:%d, range:%d, group:%d", curModInfo->mod_name, curModInfo->epid, curModInfo->range, curModInfo->group);
 			CloseHandle(CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&runThreadAndMonitor, curModInfo, 0, &curModInfo->threadId));
@@ -326,6 +318,9 @@ int main(int argc, char *argv[])
 	if (!mod_name || !strlen(mod_name)) {
 		return -300;
 	}
+
+	WLog_initRVC(mod_name);
+
 	SetEnvPath(mod_name);
 	rc = SpRun(mod_name, epid, range, 0);
 

+ 6 - 9
spshell/spshell.cpp

@@ -78,6 +78,8 @@ static void SetEnvPath()
 
 	SetEnvironmentVariableA(var, buf);
 	free(buf);
+
+	SetEnvironmentVariableA("ModuleName", "SpShell");
 }
 
 #ifdef _WIN32
@@ -736,19 +738,14 @@ BeforeLeave:
 
 #endif //_WIN32
 
+
+
 int main(int argc, char **argv)
 {
+	WLog_initRVC("SpShell");
 #ifdef _WIN32
 	_CrtSetDebugFillThreshold(0);
 #endif //_WIN32
-
-	SetEnvironmentVariableA("WLOG_APPENDER", "FILE");
-#ifndef _WIN32
-	SetEnvironmentVariableA("WLOG_FILEAPPENDER_OUTPUT_FILE_PATH", "/opt/wlog");
-#else
-	SetEnvironmentVariableA("WLOG_FILEAPPENDER_OUTPUT_FILE_PATH", "C:\\wlog");
-#endif //NOT _WIN32
-
 	sp_dbg_init("SpShell");
 	sp_dbg_info("===================SpShell start=====================");
 		
@@ -866,7 +863,7 @@ int main(int argc, char **argv)
 	else
 	{
 		sp_dbg_error("======================================================");
-		sp_dbg_error("!!!!!! Startup failed, get more detail information from dbg\\spshell !!!!!!");
+		sp_dbg_error("!!!!!! Startup failed, get more detail information from dbg/spshell !!!!!!");
 		sp_dbg_error("======================================================");
 
 		Sleep(10000);

+ 3 - 0
winpr/include/winpr/wlog.h

@@ -218,6 +218,9 @@ extern "C"
 	};
 	typedef struct _wLogCallbacks wLogCallbacks;
 
+
+	WINPR_API void WLog_initRVC(const char* key);
+
 #ifdef __cplusplus
 }
 #endif

+ 62 - 4
winpr/libwinpr/utils/wlog/FileAppender.c

@@ -40,6 +40,8 @@ struct _wLogFileAppender
 };
 typedef struct _wLogFileAppender wLogFileAppender;
 
+static SYSTEMTIME LogDateTime = { 0 };
+
 static BOOL WLog_FileAppender_SetOutputFileName(wLogFileAppender* appender, const char* filename)
 {
 	appender->FileName = _strdup(filename);
@@ -79,18 +81,21 @@ static BOOL WLog_FileAppender_Open(wLog* log, wLogAppender* appender)
 
 	if (!fileAppender->FileName)
 	{
-		fileAppender->FileName = (char*)malloc(MAX_PATH);
+		SYSTEMTIME localTime;
+		fileAppender->FileName = (char*) malloc(MAX_PATH);
 
 		if (!fileAppender->FileName)
 			return FALSE;
+		GetLocalTime(&localTime);
 
-		sprintf_s(fileAppender->FileName, MAX_PATH, "%" PRIu32 ".log", GetCurrentProcessId());
+		//sprintf_s(fileAppender->FileName, MAX_PATH, "%"PRIu32".log", GetCurrentProcessId());
+		sprintf_s(fileAppender->FileName, MAX_PATH, "%u%02u%02u.log", localTime.wYear, localTime.wMonth, localTime.wDay);
+		CopyMemory(&LogDateTime, &localTime, sizeof(SYSTEMTIME));
 	}
 
 	if (!fileAppender->FullFileName)
 	{
-		fileAppender->FullFileName =
-		    GetCombinedPath(fileAppender->FilePath, fileAppender->FileName);
+		fileAppender->FullFileName = GetCombinedPath(fileAppender->FilePath, fileAppender->FileName);
 
 		if (!fileAppender->FullFileName)
 			return FALSE;
@@ -129,6 +134,58 @@ static BOOL WLog_FileAppender_Close(wLog* log, wLogAppender* appender)
 	return TRUE;
 }
 
+static BOOL WLog_FileAppender_ReOpenFileDescriptor(wLog* log, wLogAppender* appender)
+{
+	char format[MAX_PATH];
+	wLogFileAppender* fileAppender;
+	BOOL bReopen = FALSE;
+	SYSTEMTIME localTime;
+	if (!log || !appender)
+		return FALSE;
+
+	fileAppender = (wLogFileAppender*)appender;
+
+	if (!fileAppender->FileDescriptor)
+		return FALSE;
+	GetLocalTime(&localTime);
+
+	//sprintf_s(format, MAX_PATH, "%"PRIu32".log", GetCurrentProcessId());
+	//if (!strcmp(fileAppender->FileName, format)) {
+	//	bReopen = TRUE;
+	//}
+	//if (!bReopen)
+	{
+
+	}
+	if (LogDateTime.wYear == 0
+		||
+		!(LogDateTime.wYear == localTime.wYear
+		&& LogDateTime.wMonth == localTime.wMonth
+		&& LogDateTime.wDay == localTime.wDay))
+	{
+		if (WLog_FileAppender_Close(log, appender))
+		{
+			free(fileAppender->FileName);
+			fileAppender->FileName = NULL;
+			free(fileAppender->FullFileName);
+			fileAppender->FullFileName = NULL;
+
+			//fileAppender->FileName = (char*)malloc(MAX_PATH);
+
+			//if (!fileAppender->FileName)
+			//	return FALSE;
+			//sprintf_s(fileAppender->FileName, MAX_PATH, "%u%02u%02u.log", localTime.wYear, localTime.wMonth, localTime.wDay);
+
+			if (WLog_FileAppender_Open(log, appender))
+			{
+				//CopyMemory(&LogDateTime, &localTime, sizeof(SYSTEMTIME));
+				return TRUE;
+			}
+		}
+	}
+	return FALSE;
+}
+
 static BOOL WLog_FileAppender_WriteMessage(wLog* log, wLogAppender* appender, wLogMessage* message)
 {
 	FILE* fp;
@@ -139,6 +196,7 @@ static BOOL WLog_FileAppender_WriteMessage(wLog* log, wLogAppender* appender, wL
 		return FALSE;
 
 	fileAppender = (wLogFileAppender*)appender;
+	WLog_FileAppender_ReOpenFileDescriptor(log, appender);
 	fp = fileAppender->FileDescriptor;
 
 	if (!fp)

+ 12 - 0
winpr/libwinpr/utils/wlog/wlog.c

@@ -1011,3 +1011,15 @@ BOOL WLog_Uninit(void)
 {
 	return TRUE;
 }
+
+void WLog_initRVC(const char* key)
+{
+	char t[256] = { '\0' };
+	SetEnvironmentVariableA("WLOG_APPENDER", "FILE");
+#ifndef _WIN32
+	sprintf(t, "/opt/wlog/%s", key);
+#else
+	sprintf(t, "C:\\wlog\\%s", key);
+#endif //NOT _WIN32
+	SetEnvironmentVariableA("WLOG_FILEAPPENDER_OUTPUT_FILE_PATH", t);
+}