分布式小练习FastDFS, exec 函数复习,log模块集成 gdb调试复习,Makefile

4 篇文章 0 订阅

安装配置好FastDFS之后,运行起来;

通过fdfs_monitor测试storage状态,正常状态必须是ACTIVE,否则无法上传、下载文件:

在Qt中编辑一下main函数,实现log的集成,做少量修改,log中重定向标准输出到log文件指定的路径中;



记错exec函数以为它会自动创建一个子进程执行系统命令,导致最后一直没有正确的log文件,导致exec后面的调试信息一直没有打印正确。

正好复习了 gdb调试,

注意的细节 1.要调试程序,必须在gcc编译时加 -g

2.多文件调试加断点方法: b main.c:23    

3.当编译出来的可执行程序需要外部输入参数时,可以在调试过程中执行运行命令 r 时添加要加入的参数: r /etc/fdfs/client.config main.c

其他知识点:

1.dup2函数是在全局有效的,即一旦执行修改,那么整个进程中标准输出一直被log文件的文件描述符覆盖。

2.    

函数 l 参数表示参数列表;v表示参数是数组;

p --->PATH环境变量   e---->environ环境变量

什么都不加时,需要在参数中指定绝对路径;

	execlp(cmd, cmd, arg1, arg2, NULL );      参数是列表的函数(带有 l 选项)参数很特殊,前俩是重复的,最后参数列表要以 NULL  结束。

3.exec函数是将执行该函数的进程从执行代码的序列中跳出去执行系统命令,执行完后不会返回调用该函数的代码序列中;所以一般需要配合fork使用。 

main.c如下:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include "include/mylog.h"

/*	0 -- 没有日志
        1 -- debug级别
        2 -- info级别
        3 -- warning级别
        4 -- err级别
*/
int main(int argc,char* argv[])
{
    printf("begin...\n");
    My_Log(__FILE__,__LINE__, ELevel[2], 0, "%s", "main function start");
//    char*file_conf = argv[1];
//    char *file_upload = argv[2];
    char* file_conf = "/etc/fdfs/client.conf";
    char* file_upload = "main.c";

    //execlp(cmd, cmd, arg1, arg2, ... );
    //exec函数是将执行该函数的进程从执行代码的序列中跳出去执行系统命令,执行完后不会返回调用该函数的代码序列中;所以一般需要配合fork使用。
    if(0 == fork())
    {
        int ret =0;
        ret = execlp("fdfs_upload_file", "fdfs_upload_file", file_conf, file_upload, NULL);

        if(ret ==-1)
        {
            My_Log(__FILE__,__LINE__, ELevel[4], ret, "%s,%s", "execlp function err",strerror(errno));
            printf("*************************\n");
            return -1;
        }
        exit(0);
    }
    wait(NULL);
    printf("*************************\n");
    My_Log(__FILE__,__LINE__, ELevel[2], 0, "%s", "execlp function OK");
    return 0;
}


使用Qt编写linux代码,需要配合Makefile才可以在Qt环境下编译,下面为Makefile:

src = $(wildcard *.c)
obj = $(patsubst %.c, %.o, $(src))
target = a.out

all: $(target)

$(target):$(obj)
	gcc $^ -o $@	

$(obj): %.o: %.c
	gcc -c $< -o $@	

.PHONY: clean
clean:
	-rm -rf $(target) $(obj)



include/mylog.h内容
#ifndef _MY_LOG_H_
#define _MY_LOG_H_

//实际使用的Level
extern int  ELevel[5];
void My_Log(const char *file, int line, int level, int status, const char *fmt, ...);

#endif


mylog.c
#define  _CRT_SECURE_NO_WARNINGS 

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdarg.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#include "include/mylog.h"

#define DEBUG_FILE	"fdfs_client.log"
#define MAX_STRING_LEN 		10240

//Level类别
#define NO_LOG_LEVEL			0
#define DEBUG_LEVEL			1
#define INFO_LEVEL			2
#define WARNING_LEVEL		3
#define ERROR_LEVEL			4

int  ELevel[5] = {NO_LOG_LEVEL, DEBUG_LEVEL, INFO_LEVEL,WARNING_LEVEL,ERROR_LEVEL};

//Level的名称
char ELevelName[5][10] = {"NOLOG", "DEBUG", "INFO", "WARNING", "ERROR"};

static int Error_GetCurTime(char* strTime)
{
	struct tm*		tmTime = NULL;
	size_t			timeLen = 0;
	time_t			tTime = 0;	
	
	tTime = time(NULL);
	tmTime = localtime(&tTime);
	//timeLen = strftime(strTime, 33, "%Y(Y)%m(M)%d(D)%H(H)%M(M)%S(S)", tmTime);
	timeLen = strftime(strTime, 33, "%Y.%m.%d %H:%M:%S", tmTime);
	
	return timeLen;
}

static int Error_OpenFile(int* pf)
{
	char	fileName[1024];
	
	memset(fileName, 0, sizeof(fileName));
#ifdef WIN32
    sprintf(fileName, "c:\\Users\\BLACK007\\Desktop\\%s",DEBUG_FILE);
#else
    sprintf(fileName, "%s/File of Test/2_4fdfs/log/%s", getenv("HOME"), DEBUG_FILE);
#endif
   //File of Test/2_4fdfs/
    *pf = open(fileName, O_WRONLY|O_CREAT|O_APPEND, 0666);
    if(*pf < 0)
    {
        //printf("************open error\n");
        return -1;
    }
	
	return 0;
}

static void Error_Core(const char *file, int line, int level, int status, const char *fmt, va_list args)
{
    char str[MAX_STRING_LEN];
    int	 strLen = 0;
    char tmpStr[64];
    int	 tmpStrLen = 0;
    int  pf = 0;
    
    //初始化
    memset(str, 0, MAX_STRING_LEN);
    memset(tmpStr, 0, 64);

    //加入LOG时间
    tmpStrLen = Error_GetCurTime(tmpStr);
    tmpStrLen = sprintf(str, "[%s] ", tmpStr);
    strLen = tmpStrLen;


    //加入LOG等级
    tmpStrLen = sprintf(str+strLen, "[%s] ", ELevelName[level]);
    strLen += tmpStrLen;
    
    //加入LOG状态
    if (status != 0) 
    {
        tmpStrLen = sprintf(str+strLen, "[ERRNO is %d] ", status);
    }
    else
    {
    	tmpStrLen = sprintf(str+strLen, "[SUCCESS] ");
    }
    strLen += tmpStrLen;

    //加入LOG信息
    tmpStrLen = vsprintf(str+strLen, fmt, args);
    strLen += tmpStrLen;

    //加入LOG发生文件
    tmpStrLen = sprintf(str+strLen, " [%s]", file);
    strLen += tmpStrLen;

    //加入LOG发生行数
    tmpStrLen = sprintf(str+strLen, " [%d]\n", line);
    strLen += tmpStrLen;
    
    //打开LOG文件
    if(0 == Error_OpenFile(&pf))
	{
        	dup2(pf,STDOUT_FILENO);        //dup2函数是在全局有效的,即一旦执行修改,那么整个进程中标准输出一直被log文件的文件描述符覆盖。
        return ;
	}
	
    //写入LOG文件
    write(pf, str, strLen);
    //Log_Error_WriteFile(str);
    
    //关闭文件
    close(pf);
    
    return ;
}


void My_Log(const char *file, int line, int level, int status, const char *fmt, ...)
{
    va_list args;
	//判断是否需要写LOG
//	if(level!=DEBUG_LEVEL && level!=INFO_LEVEL && level!=WARNING_LEVEL && level!=ERROR_LEVEL)
    if(level == NO_LOG_LEVEL)
	{
		return ;
	}

	//调用核心的写LOG函数
    va_start(args, fmt);
    Error_Core(file, line, level, status, fmt, args);
    va_end(args);


    return ;
}


 





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值