MTK功能平台远程上传LOG到七牛服务器
MT6261,MT2503 等功能平台因储存空间有限,平时产品上打印日志文件过多,只能本地删除重新写入新日志。旧日志被删除,无法记录全天侯甚至一个月的系统日志。今天开源远程上传本地日志源码。使用的服务器是 七牛服务器 ,七牛服务虽然提供了linux c 版本的api,但是无法适合用MTK平台。
/* 头文件 */
#ifndef __REPORT_LOG_H__
#define __REPORT_LOG_H__
#include "MMI_include.h"
#include "kal_public_defs.h"
#include "Nvram_user_defs.h"
#include "conversions.h"
#include "task_main_func.h"
#include "app_ltlcom.h"
#include "task_config.h"
#include "syscomp_config.h"
#include "custom_util.h"
#include "stack_ltlcom.h"
#include "kal_non_specific_general_types.h"
#include "stack_config.h"
#include "custom_config.h"
#include "stack_timer.h"
#include "custom_config.h"
#include "med_utility.h"
#include "profilessrvgprot.h"
#include "DateTimeType.h"
#include "mmi_rp_srv_prof_def.h"
#include "gpiosrvgprot.h"
#include "mdi_audio.h"
#include "mdi_gps.h"
#include "aud_defs.h"
#include "mmi_rp_app_charger_def.h"
#include "GeneralDeviceGprot.h"
#include "TimerEvents.h"
#include "stack_msgs.h"
#include "soc_api.h"
#include "cbm_api.h"
#include "DtcntSrvGprot.h"
#include "App_datetime.h"
#include "wndrv_cnst.h"
#include "FileMgrSrvGProt.h"
#include "nbr_public_struct.h"
#include "CharBatSrvGprot.h"
#include "NwInfoSrvGprot.h"
#include "wmp_socket.h"
#include "wmp_gps.h"
#include "cJSON.h"
#include "wmp_timerevent.h"
#define MAX_LOGS_SAVE 20
#define MAX_LEN_LOG 30
typedef struct _ReportLogSocket{
sockaddr_struct rl_addr;
signed rl_socHand;
kal_uint32 rl_account_id;
U8 *rl_sendbuff;
U32 rl_sendbuff_lenth;
U8 *rl_recvBuff;
U32 rl_recvBuff_lenth;
kal_uint32 account_id;
WCHAR LogFilesPath[MAX_LOGS_SAVE][MAX_LEN_LOG*2];
WCHAR currFilePath[MAX_LEN_LOG*2];
}ReportLogSocket;
#endif
每次上传13K文本日志。文件名以 IMEI/时间.log 命名。上传到七牛一个bucket空间。HTTP POST提交。
上传到七牛服务器需要申请帐号,得到一个AccessKey、SecretKey 等key鉴权。以下是源码实现 。
#ifdef __REPORT_LOG__
#include "wmp_reportlog.h"
#include "task_config.h"
#define LOG_FILE_PATH L"c:\\wmp_log.txt"
#define END_LINE_CONTENT "\n\r\n------------------------------01a9d769ec15--\r\n"
#define MAX_GET_SIZE (1024*13) /* 最大每次发送15K */
kal_uint32 offset_size = 0;
int wmp_ReportLogIsEmpt(void);
extern void wmp_trace_log(char* fmt,...);
void wmp_ReportLog(void);
kal_uint32 wmp_ReportLogGetFileSize( kal_wchar *path );
void wmp_ReportLogReadFileLog(kal_wchar *path,char *package,int package_lenth,U32 offset_package,kal_uint32 *package_readLenth);
extern kal_uint32 wmp_GetGPRSAccount(void);
ReportLogSocket rl_socket={0};
WCHAR * wmp_ReportPopLogFilePath( void );
void wmp_ReportPushLogFilePath(WCHAR *path);
void wmp_RoportLOG_sync_filepath(void);
void wmp_ReportLogRead (U16 result)
{
#define SOC_RECV_READ_LENTH (1500)
#define TOTAL_RECV_LENTH (1024*50)
ReportLogSocket *p = &rl_socket;
int buffer_len=0;
S32 ret = 0;
p->rl_recvBuff = wmp_Malloc(TOTAL_RECV_LENTH);
if(p->rl_recvBuff)
{
memset(p->rl_recvBuff,0,TOTAL_RECV_LENTH);
/* 这里要做一层接收大文件,内存越界处理。现暂时用于LOG,不处理了。 */
do{
ret = soc_recv(p->rl_socHand, (void *)(p->rl_recvBuff+buffer_len), SOC_RECV_READ_LENTH, 0);
if(ret >= 0)
buffer_len += ret;
}while(ret > 0);
if(strstr(p->rl_recvBuff,"200 OK\r\n"))
{
kal_prompt_trace(MOD_CC,"LOG 发送成功 ");
if(wmp_ReportLogIsEmpt() != -1)
{
wmp_ReportLog();
}
}
}
else
{
wmp_trace_log("soc 分配内存失败");
}
if(p->rl_recvBuff)
{
wmp_Free(p->rl_recvBuff);
p->rl_recvBuff = NULL;
}
}
char sl_tmpPacket[500] = {0};
int wmp_sendsize(void)
{
if(wmp_ReportLogGetFileSize(wmp_ReportPopLogFilePath()) <= MAX_GET_SIZE)
{
return wmp_ReportLogGetFileSize(wmp_ReportPopLogFilePath());
}
else
return MAX_GET_SIZE;
}
void wmp_ReportLogSendHttpHead( void )
{
extern char sys_imei[20];
S32 ret = 0;
ReportLogSocket *p = &rl_socket;
char sl_bodyLenth[10]={0};
char sl_packet[1024]={0};
MYTIME time;
char time_str[128] = {0};
char filename_[50]={0};
char *realaddr = NULL;
DTGetRTCTime(&time);
mmi_wcs_to_asc(filename_, wmp_ReportPopLogFilePath());
realaddr = strstr(filename_,"C:\\Log\\")+strlen("C:\\Log\\");
strcpy(filename_,realaddr);
sprintf(time_str, "%s/%s",
sm_GetIMEI(),filename_);
strcpy(sl_packet,"POST / HTTP/1.1\r\nHost: upload.qiniu.com\r\nAccept: */*\r\nContent-Length: ");
strcpy(sl_tmpPacket,"");
strcat(sl_tmpPacket,"------------------------------01a9d769ec15\r\n");
strcat(sl_tmpPacket,"Content-Disposition: form-data; name=\"token\"\r\n\r\n");
//strcat(sl_tmpPacket,"你的AccessKey \r\n");
strcat(sl_tmpPacket,"你的AccessKey\r\n");
strcat(sl_tmpPacket,"------------------------------01a9d769ec15\r\nContent-Disposition: form-data; name=\"key\"\r\n\r\n");
strcat(sl_tmpPacket,time_str);
strcat(sl_tmpPacket,"\r\n------------------------------01a9d769ec15\r\nContent-Disposition: form-data; name=\"file\"; filename=\"wmp_log.txt\"\r\nContent-Type: text/plain\r\n\r\n");
sprintf(sl_bodyLenth,"%d",wmp_sendsize()+strlen(END_LINE_CONTENT)+strlen(sl_tmpPacket));
strcat(sl_packet,sl_bodyLenth);
strcat(sl_packet,"\r\nContent-Type: multipart/form-data; boundary=----------------------------01a9d769ec15\r\n\r\n");
strcat(sl_packet,sl_tmpPacket);
ret = soc_send(p->rl_socHand, (U8*) (sl_packet), strlen(sl_packet), 0);
wmp_trace_log("发送LOG头。ret:%d",ret);
}
void wmp_ReportGetLogContent( void )
{
FS_HANDLE file_handle;
kal_uint32 filesize=0;
U8 read_flag;
S32 fs_ret;
U32 nRW;
ReportLogSocket *p = &rl_socket;
memset(p->currFilePath,0,sizeof(p->currFilePath));
mmi_wcscpy(p->currFilePath, wmp_ReportPopLogFilePath());
if(p->currFilePath)
{
file_handle = FS_Open(p->currFilePath,FS_READ_WRITE);
if (file_handle > FS_NO_ERROR)
if(FS_GetFileSize(file_handle, &filesize) == FS_NO_ERROR)
{
if(filesize < MAX_GET_SIZE)
{
p->rl_sendbuff = wmp_Malloc(filesize+1);
memset(p->rl_sendbuff,0,filesize+1);
fs_ret = FS_Read(file_handle, p->rl_sendbuff, filesize, &nRW);
p->rl_sendbuff_lenth = nRW;
}
else
{
p->rl_sendbuff = wmp_Malloc(MAX_GET_SIZE+1);
memset(p->rl_sendbuff,0,MAX_GET_SIZE+1);
fs_ret = FS_Read(file_handle, p->rl_sendbuff, MAX_GET_SIZE, &nRW);
p->rl_sendbuff_lenth = nRW;
}
wmp_trace("文件总大小 %d 读到 %d",filesize,nRW);
}
FS_Close(file_handle);
}
}
static void wmp_ReportLogTaskNotifyInternal(void* Content)
{
ReportLogSocket *p = &rl_socket;
app_soc_notify_ind_struct *soc_notify = (app_soc_notify_ind_struct *) Content;
S32 ret = 0;
kal_uint32 file_read_lenth = 0;
switch (soc_notify->event_type)
{
case SOC_WRITE:
//wmp_ReportSendFile();
break;
case SOC_READ:
{
wmp_ReportLogRead(soc_notify->event_type);
}
break;
case SOC_CONNECT:
{
kal_uint32 filesize= wmp_ReportLogGetFileSize(wmp_ReportPopLogFilePath());
wmp_RoportLOG_sync_filepath();
if(filesize != 0)
{
char file_path[100]={0};
char temp[100]={0};
int fs_err;
mmi_wcs_to_asc(file_path, wmp_ReportPopLogFilePath());
wmp_ReportLogSendHttpHead();
wmp_ReportGetLogContent();
ret = soc_send(p->rl_socHand, (U8*) (p->rl_sendbuff), p->rl_sendbuff_lenth, 0);
ret = soc_send(p->rl_socHand, (U8*) END_LINE_CONTENT, strlen(END_LINE_CONTENT), 0);
if(p->rl_sendbuff != NULL)
{
p->rl_sendbuff_lenth = 0;
wmp_Free(p->rl_sendbuff);
p->rl_sendbuff = NULL;
}
fs_err = FS_Delete(p->currFilePath);
mmi_wcs_to_asc(temp, p->currFilePath);
if(wmp_ReportDeleteFileFromPath(p->currFilePath) < 0)
{
wmp_trace_log("LOG文件删除失败..%s",temp);
}
if(fs_err < FS_NO_ERROR)
{
}
kal_prompt_trace(MOD_CC,"report log :%d,path:%s 删除结果:%d",filesize,file_path,fs_err);
}
}
break;
case SOC_ACCEPT:
break;
case SOC_CLOSE:
{
//关闭
p->rl_socHand=-1;
}
default:
break;
break;
}
}
/* 初始化Task */
kal_bool wmp_initReportLogTask( task_indx_type task_indx )
{
ReportLogSocket *p = &rl_socket;
p->rl_recvBuff = NULL;
p->rl_sendbuff = NULL;
p->rl_socHand = -1;
return KAL_TRUE;
}
/* Task处理 */
void wmp_ReportLogTaskEntry( task_entry_struct *task_entry_ptr )
{
ilm_struct current_ilm;
kal_uint32 task_index=0;
kal_get_my_task_index(&task_index);
stack_set_active_module_id(task_index, MOD_WMP_SOCKET);
while(1)
{
receive_msg_ext_q_for_stack(task_info_g[task_index].task_ext_qid, ¤t_ilm);
stack_set_active_module_id(task_index, current_ilm.dest_mod_id);
switch(current_ilm.msg_id)
{
case MSG_ID_APP_SOC_NOTIFY_IND:
{
wmp_ReportLogTaskNotifyInternal((void *)current_ilm.local_para_ptr);
}
break;
case MSG_ID_APP_SOC_GET_HOST_BY_NAME_IND:
{
//wmp_GetHostByNameCallBack((void *)current_ilm.local_para_ptr);
}
break;
}
free_ilm(¤t_ilm);
}
}
kal_bool wmp_ReportLogTaskCreate( comptask_handler_struct **handle )
{
static const comptask_handler_struct custom2_handler_info = {
wmp_ReportLogTaskEntry, /* task entry function */
wmp_initReportLogTask, /* task initialization function */
NULL, /* task configuration function */
NULL, /* task reset handler */
NULL, /* task termination handler */
};
*handle = ( comptask_handler_struct * )&custom2_handler_info;
return KAL_TRUE;
}
void wmp_ReportLogCloseSocket(void)
{
ReportLogSocket *p = &rl_socket;
wmp_trace_log("wmp_ReportLogCloseSocket...");
if(p->rl_socHand == SOC_LIMIT_RESOURCE)
{
int i = 0;
wmp_trace_log("wmp_ReportLogCloseSocket受限制的句柄,全部关闭一下。");
for(i=0;i<MAX_IP_SOCKET_NUM;i++)
{
soc_close(i);
kal_sleep_task(10);
}
p->rl_socHand = -1;
}
if(p->rl_socHand != -1)
{
soc_close(p->rl_socHand);
p->rl_socHand=-1;
}
}
void wmp_ReportLogGetHost(sockaddr_struct * addr)
{//183.39.156.37
addr->addr[0] =58;//192;//58;
addr->addr[1] = 63;//168;//63;
addr->addr[2] = 233; //124;//33;
addr->addr[3] = 33 ;//124;//33;
addr->port = 80;
addr->addr_len = 4;
addr->sock_type = SOC_SOCK_STREAM;
}
int wmp_ReportLogIsEmpt(void)
{
ReportLogSocket *p = &rl_socket;
int i=0;
for(;i<MAX_LOGS_SAVE;i++)
{
if(mmi_wcslen(p->LogFilesPath[i]) != 0)
{
return i;
}
else
continue;
}
return -1;
}
WCHAR * wmp_ReportPopLogFilePath( void )
{
ReportLogSocket *p = &rl_socket;
int i=0;
for(;i<MAX_LOGS_SAVE;i++)
{
if(mmi_wcslen(p->LogFilesPath[i]) != 0)
{
return p->LogFilesPath[i];
}
else
continue;
}
return NULL;
}
int wmp_ReportDeleteFileFromPath(WCHAR *filePath)
{
ReportLogSocket *p = &rl_socket;
int i=0;
if(mmi_wcslen(filePath) == 0) return -1;
for(;i<MAX_LOGS_SAVE;i++)
{
if(!mmi_wcscmp(p->LogFilesPath[i],filePath))
{
mmi_wcscpy(p->LogFilesPath[i],L"");
return i;
}
}
return -1;
}
void wmp_ReportPushLogFilePath(WCHAR *path)
{
ReportLogSocket *p = &rl_socket;
int i=0,isPush = 0;
for(;i<MAX_LOGS_SAVE;i++)
{
if(mmi_wcslen(p->LogFilesPath[i]) == 0)
{
mmi_wcscpy(p->LogFilesPath[i],path);
isPush = 1;
break;
}
else
continue;
}
if(!isPush)
{
applib_file_delete_folder(L"C:\\Log");
memset(p->LogFilesPath,0,sizeof(p->LogFilesPath));
for(;i<MAX_LOGS_SAVE;i++)
{
if(mmi_wcslen(p->LogFilesPath[i]) == 0)
{
mmi_wcscpy(p->LogFilesPath[i],path);
break;
}
else
continue;
}
}
}
void wmp_RoportLOG_sync_filepath(void)
{
#define VDOPLY_HISTORY_BUF_LEN (50)
FS_DOSDirEntry file_info;
CHAR buf_filename[(VDOPLY_HISTORY_BUF_LEN+1) * ENCODING_LENGTH];
FS_HANDLE file_handle;
S16 error;
int i = 0;
S32 fs_ret;
CHAR filter[(VDOPLY_HISTORY_BUF_LEN+1) * ENCODING_LENGTH];
ReportLogSocket *p = &rl_socket;
mmi_ucs2cpy((CHAR*)filter, (CHAR*)L"C:\\Log\\*.log");
memset(p->LogFilesPath,0,sizeof(p->LogFilesPath));
file_handle = FS_FindFirst(
(U16*)filter,
0,
0,
&file_info,
(U16*)buf_filename,
sizeof(buf_filename));
if (file_handle > 0)
{
do
{
WCHAR file_path[100]={0};
fs_ret = FS_FindNext(
file_handle,
&file_info,
(PU16)buf_filename,
sizeof(buf_filename));
mmi_wcscpy(file_path,L"C:\\Log\\");
mmi_wcscat(file_path,(U16*)buf_filename);
mmi_wcscpy(p->LogFilesPath[i], file_path);
i++;
}while (fs_ret == FS_NO_ERROR);
FS_FindClose(file_handle);
}
}
kal_uint32 wmp_ReportLogGetFileSize( kal_wchar *path )
{
FS_HANDLE file_handle;
kal_uint32 filesize=0;
if(path)
{
file_handle = FS_Open(path,FS_READ_ONLY);
if (file_handle >= FS_NO_ERROR)
if(FS_GetFileSize(file_handle, &filesize) == FS_NO_ERROR)
{
}
FS_Close(file_handle);
}
return filesize;
}
/* package_lenth:每次最大读取的文件size */
void wmp_ReportLogReadFileLog(kal_wchar *path,char *package,int package_lenth,U32 offset_package,kal_uint32 *package_readLenth)
{
FS_HANDLE file_handle;
kal_uint32 filesize=0;
U8 read_flag;
S32 fs_ret;
U32 nRW;
ReportLogSocket *p = &rl_socket;
file_handle = FS_Open(path,FS_READ_WRITE);
if (file_handle >= FS_NO_ERROR)
if(FS_GetFileSize(file_handle, &filesize) == FS_NO_ERROR)
{
if(filesize < package_lenth)
{
p->rl_sendbuff = wmp_Malloc(filesize);
memset(p->rl_sendbuff,0,filesize);
if(p->rl_sendbuff)
{
fs_ret = FS_Read(file_handle, p->rl_sendbuff, filesize, &nRW);
*package_readLenth= nRW;
}
}
else if((filesize > package_lenth)&&(offset_package < filesize))
{
p->rl_sendbuff = wmp_Malloc(package_lenth);
memset(p->rl_sendbuff,0,package_lenth);
if(p->rl_sendbuff)
{
FS_Seek(
file_handle,
offset_package,
FS_FILE_BEGIN);
fs_ret = FS_Read(file_handle, p->rl_sendbuff, package_lenth, &nRW);
*package_readLenth = nRW;
//wmp_trace_log("读取文件长度:%d ",nRW);
}
}
else
{
package = NULL;
*package_readLenth = 0;
}
}
FS_Close(file_handle);
}
void wmp_ReportLog(void)
{
#define VALID_SOCKET(s) (s>=0)
ReportLogSocket *p = &rl_socket;
kal_int8 ret = 0;
U8 strength = 0;
#ifndef WIN32
srv_nw_info_service_availability_enum status = srv_nw_info_get_service_availability( MMI_SIM1 );
strength = srv_nw_info_get_signal_strength_in_percentage(MMI_SIM1);
wmp_ReportLogCloseSocket();
kal_prompt_trace(MOD_CC,"LOG 提交信号:%d 强度:%d",status,strength);
#endif
wmp_ReportLogGetHost(&p->rl_addr);
if(!VALID_SOCKET(p->rl_socHand))
{
U8 val = 1;
if(p->account_id == 0)
p->account_id = wmp_GetGPRSAccount();
p->rl_socHand = soc_create(SOC_PF_INET, p->rl_addr.sock_type, 0, MOD_REPORT_LOG, p->account_id);
if (soc_setsockopt(p->rl_socHand, SOC_NBIO, &val, sizeof(val)) < 0)
{
//错误
//return ;
}
val = SOC_READ | SOC_WRITE | SOC_CLOSE | SOC_CONNECT;
if (soc_setsockopt(p->rl_socHand, SOC_ASYNC, &val, sizeof(val)) < 0)
{
//错误
//return;
}
if(p->rl_addr.sock_type == SOC_SOCK_STREAM)
{
ret = soc_connect(p->rl_socHand, &p->rl_addr);
}
else
{
//错误
}
}
else
{
wmp_ReportLogCloseSocket();
}
StartTimer(WMP_TIMER_EVNET_20,1000*60*60,wmp_ReportLog);
}
#endif
效果图: