精华内容
下载资源
问答
  • C++ 多线程日志记录

    2018-09-07 12:42:20
    使用该类可实现C++ 多线程日志的记录,创建了日志记录线程,使用日志等级、队列、信号量、临界区等方法实现记录,可在较高的实时性系统上完成日志记录。
  • 单例模式+多线程日志类程序思路主要问题和解决思路:疑问完整代码运行结果 程序思路 想自己写一个日志类来记录一些日志信息、该日志类需要支持多线程。为了避免出现多个线程写日志文件的情况*(多个线程写文件、需要...

    程序思路

    想自己写一个日志类来记录一些日志信息、该日志类需要支持多线程。为了避免出现多个线程写日志文件的情况*(多个线程写文件、需要频繁加锁、解锁、写文件)*决定使用“队列”来解决多个线程写文件的问题,即多个线程往日志信息队列中放信息、一个real写文件线程负责从队列头取日志并写入文件。

    主要问题和解决思路:

    1、提供给使用者的接口、即使用者调用哪个函数来实现日志的记录。
    2、负责写日志信息的函数(线程Dolog)。
    该线程应该是在创建日志对象时就创建、这就需要对象构造时创建Dolog线程。
    3、如何保证日志类只有一个实例?单例模式相关文章都有讲解。

    疑问

    1、在测试代码中、注释掉system(“pause”);后、主线程在子线程完成之前结束、导致日志记录不全。这种情况改怎么解决?即怎么让日志对象知道主线程将要结束、从而让写日志线程退出(发消息?信号量)?
    2、在debug时、发现程序并没有进入Logger的析构函数(不是说程序在退出时会自动进行资源的回收、自动调用相关对象的析构函数吗)?想知道为什么会没有进入析构函数?如果没有进入析构函数、那么怎么对资源进行回收?

    完整代码

    头文件 Logger.h

    #pragma once
    #include <queue>
    #include <string>
    #include <fstream>
    #include <mutex>
    using namespace std;
    
    class Logger
    {
    public:
    	static Logger* GetInstance(){
    		if (instance==nullptr){
    			lock_guard<mutex> lk(instanceLock);//小粒度加锁
    			if (instance==nullptr){
    				instance = new Logger();
    			}
    		}
    		return instance;
    	}
    
    	static void DoLog(void* param);
    	void AddLog(string &log);
    	~Logger(void);
    
    private:
    	Logger(void);  //禁止在外面创建对象
    	Logger(Logger& logger);
    
    	static Logger *instance;
    	static mutex instanceLock;
    	mutex      queueLock;
    	queue<string> m_log_queue;
    	bool m_bExit;
        std::fstream  m_logfs; //只有一个线程操作
    };
    

    实现文件 Logger.cpp

    #include "Logger.h"
    #include <thread>
    #include <iostream>
    #include <fstream>
    #include <mutex>
    
    Logger* Logger::instance = NULL;
    mutex Logger::instanceLock;
    
    Logger::Logger(void){//创建一个从queue中读数据 并写入日志文件的线程
    	m_bExit = false;
    	(this->m_logfs).open("log.txt", std::fstream::in | std::fstream::out | std::fstream::app);
    	thread t(Logger::DoLog, this);
    	t.detach();
    }
    
    void Logger::DoLog(void* param){
    	Logger *pThis = static_cast<Logger*>(param);
    	while (true){
    		if (!pThis->m_bExit){
    			unique_lock<mutex> lk(pThis->queueLock);
    			if (!(pThis->m_log_queue).empty()){
    				string log = pThis->m_log_queue.front();
    				pThis->m_log_queue.pop();
    				pThis->m_logfs << log << endl;
    				cout << log << endl;
    			}else{
    
    			}
    		}else
    			break;
    	}
    }
    
    void Logger::AddLog(string &log){
    	unique_lock<mutex> lk(queueLock);
    	m_log_queue.push(log);
    }
    
    Logger::~Logger(void)
    {
    	if (Logger::instance!=NULL){
    		m_bExit = true;
    		m_logfs.close();
    		delete Logger::instance;
    		Logger::instance = NULL;
    	}
    }
    

    测试代码

    int main()
    {
    	clock_t start, end;
    	start = clock();
    	for (int index=0; index<9000; index++){
    		thread t(addlog, index);
    		t.join();
    	}
    	end = clock();
    	system("pause");//注释掉这一句 主线程在子线程之前就退出了
        return 0;
    }
    

    运行结果

    日志写入结果

    在查找多线程单例模式的相关资料时、有的资料说双重锁机制在C++下无效、先记录下链接供后续学习https://blog.csdn.net/linlin003/article/details/79012416

    展开全文
  • 并且需要运行16秒才能打印完这些日志要求:程序中增加4个线程去调用parseLog()方法来分头打印这16个日志对象,程序只需要运行4秒即可打印完这些日志对象上述要求,主要是考察应聘者对队列和多线程两方面的综合理解和...

    其实这是一道Java笔试题:现有的程序代码模拟产生了16个日志对象,并且需要运行16秒才能打印完这些日志

    要求:程序中增加4个线程去调用parseLog()方法来分头打印这16个日志对象,程序只需要运行4秒即可打印完这些日志对象

    上述要求,主要是考察应聘者对队列和多线程两方面的综合理解和运用!

    实现如下:import java.util.concurrent.ArrayBlockingQueue;

    /**

    * 现有的程序代码模拟产生了16个日志对象,并且需要运行16秒才能打印完这些日志

    *

    * 要求实现功能:

    * 请在程序中增加4个线程去调用parseLog()方法来分头打印这16个日志对象,程序只需要运行4秒即可打印完这些日志对象

    *

    * @author thinker

    */

    public class MultiThreadPrintLogDemo

    {

    private static boolean bFlag;

    private static long t1, t2;

    // 线程安全的日志队列【Add】

    private static ArrayBlockingQueue logQueue = new ArrayBlockingQueue(16);

    public static void main(String[] args)

    {

    // 四个线程处理16个日志对象【Add】

    t1 = System.currentTimeMillis();

    for (int i = 0; i 

    {

    // 匿名线程类

    new Thread(new Runnable()

    {

    @Override

    public void run()

    {

    while (!bFlag)

    {

    try

    {

    parseLog(logQueue.take());

    }

    catch (InterruptedException e)

    {

    e.printStackTrace();

    }

    }

    }

    }).start();

    }

    /**

    * 模拟处理16行日志,下面的代码产生了16个日志对象,当前代码需要运行16秒才能打印完这些日志。

    */

    for (int k = 0; k 

    {

    String log = String.valueOf(k);

    //parseLog(log);【Mod】

    // 【Add】

    try

    {

    logQueue.put(log);

    if (k % 4 == 0)

    {

    System.out.println("成功添加4个日志对象到日志队列!");

    }

    }

    catch (InterruptedException e)

    {

    e.printStackTrace();

    }

    }

    }

    public static void parseLog(String log)

    {

    try

    {

    Thread.sleep(1000);

    System.out.println("打印日志对象...");

    t2 = System.currentTimeMillis();

    {

    int t3 = (int)(t2 - t1) / 1000;

    System.out.println("打印日志对象截止当前共花费时间(秒):" + t3);

    if (t3 >= 4)

    {

    bFlag = true;

    }

    }

    }

    catch (InterruptedException e)

    {

    e.printStackTrace();

    }

    }

    }

    程序的运行结果:

    成功添加4个日志对象到日志队列!

    成功添加4个日志对象到日志队列!

    成功添加4个日志对象到日志队列!

    成功添加4个日志对象到日志队列!

    打印日志对象...

    打印日志对象...

    打印日志对象...

    打印日志对象...

    打印日志对象截止当前共花费时间(秒):1

    打印日志对象截止当前共花费时间(秒):1

    打印日志对象截止当前共花费时间(秒):1

    打印日志对象截止当前共花费时间(秒):1

    打印日志对象...

    打印日志对象...

    打印日志对象...

    打印日志对象...

    打印日志对象截止当前共花费时间(秒):2

    打印日志对象截止当前共花费时间(秒):2

    打印日志对象截止当前共花费时间(秒):2

    打印日志对象截止当前共花费时间(秒):2

    打印日志对象...

    打印日志对象...

    打印日志对象截止当前共花费时间(秒):3

    打印日志对象...

    打印日志对象...

    打印日志对象截止当前共花费时间(秒):3

    打印日志对象截止当前共花费时间(秒):3

    打印日志对象截止当前共花费时间(秒):3

    打印日志对象...

    打印日志对象...

    打印日志对象截止当前共花费时间(秒):4

    打印日志对象...

    打印日志对象...

    打印日志对象截止当前共花费时间(秒):4

    打印日志对象截止当前共花费时间(秒):4

    打印日志对象截止当前共花费时间(秒):4

    展开全文
  • 楼主最近刚刚接触python,还是个小菜鸟,没有学习python...通过学习python,楼主有了一种想法,想法如下可不可以分割日志,把日志分割成很多的小块,利用多线程去分析日志,这个难点在哪,难点就在如何去分割日志,...

    楼主最近刚刚接触python,还是个小菜鸟,没有学习python之前可以说楼主的shell已经算是可以了,但用shell很多东西实现起来还是不可能的事情,例如最明显的一点大日志分析,由于楼主的公司,每天的日志量很大,用shell分析的会非常非常的慢。

    通过学习python,楼主有了一种想法,想法如下

    可不可以分割日志,把日志分割成很多的小块,利用多线程去分析日志,这个难点在哪,难点就在如何去分割日志,前几篇文件楼主写过日志分割的python版,但是存在很大的弊端,只能够针对小日志进行分割,因为上一篇是把日志先写到列表中,大家都知道列表时要站内存的,那如果说日志很大,岂不一下就把内存吃满了。废话就不多说了,楼主来阐明下如何解决此问题

    首先创建一个文本,文本内容如下

    1

    2

    3

    1000

    1.计算出文本一行的大小比如说是4B

    2.用服务器的总内存数除以4B 计算出我的服务器可以一次性分析多大的文件,这个数就是我一个文本应该为多少行,也就是说我切割的日志,一个文件是多少行

    下面奉献出日志切割的脚本

    #!/usr/bin/python

    from time import ctime

    def splitFile(fileLocation, targetFoler):

    file_handler = open(fileLocation, ‘r’)

    block_size = 100   (为我每个文件的行数)

    line = file_handler.readline()

    temp = []

    countFile = 1

    while line:

    for i in range(block_size):

    if i == (block_size-1):

    # write block to small files

    file_writer = open(targetFoler + “file_”+str(countFile)+”.txt”, ‘a+’)

    file_writer.writelines(temp)

    file_writer.close()

    temp = []

    print ”  file ” + str(countFile) + ” generated at: ” + str(ctime())

    countFile = countFile + 1

    else:

    temp.append(file_handler.readline())

    if countFile == 11:

    break;

    file_handler.close()

    if __name__ == ‘__main__’:

    print “Start At: ” + str(ctime())

    splitFile(“/home/python/test.txt”, “/tmp/”)

    分割完日志后,下面就该进行日志分析了

    脚本如下

    #!/usr/bin/python

    import os

    import re

    import threading

    def chaFile(path):

    a=os.listdir(path)

    for i in range(len(a)):

    b=a[i]

    c=open(“/home/python/rizhifenge.txt”,”a+”)

    kk=”\n”+b

    c.writelines(kk)

    c.close()

    d=open(“/home/python/rizhifenge.txt”,”r”)

    f=d.read()

    e=re.findall(“file.*”,f)

    return e

    d.close()

    def chaZhao(path):

    aa=open(path,”r+”)

    bb=aa.read()

    cc=re.search(“\d.”,bb)

    if cc:

    print cc.group()

    aa.close()

    if __name__ == “__main__”:

    ff=”/tmp/”

    for i in chaFile(ff):

    gg=ff+i

    a=threading.Thread(target=chaZhao,args=(gg,))

    a.start()

    展开全文
  • 多线程日志工具源码 项目描述 运行环境: .NET Framework 4.0 可打开源码降级至.NET Framework 2.0 或者 .NET Framework 3.5 技术特点: 多线程的Log工具,将程序中需要做log的地方输出至文件,无阻塞,无资源...
  • 多线程日志追踪

    2019-10-10 11:48:28
    由于项目中设计高并发内容,涉及到一个线程创建个子线程的情况。 那么,如何跟踪日志,识别子线程是由哪个主线程创建的,属于哪个request请求。 例如, 在现有项目中,一个设备信息上传的请求(包括基本数据和...

    本文编写主要目的是记录工作中的一些编程思想和细节,以便后来查阅。

    1.问题描述

    由于项目中设计高并发内容,涉及到一个线程创建多个子线程的情况。 那么,如何跟踪日志,识别子线程是由哪个主线程创建的,属于哪个request请求。

    例如, 在现有项目中,一个设备信息上传的请求(包括基本数据和异常数据两种数据),然后主线程创建两个子线程,来处理基本数据和异常数据。

    简化代码如下:

    public class mainApp {
        public static void main(String[] args) {
            Thread t = new Thread(new Runnable() {
                @Override
                public void run() {
                    //接收到一个request
                    System.out.println("[Thread-"+ Thread.currentThread().getId() +"]开始发起请求");
                    String[] data = {"异常数据","基本数据"};
                    //创建子线程1,处理异常数据
                    MThread mThread1 = new MThread(new Runnable() {
                        @Override
                        public void run() {
                            System.out.println("[Thread-"+ Thread.currentThread().getId() +"]处理了" + data[0]);
                        }
                    });
                    创建子线程2,处理普通数据
                    MThread mThread2 = new MThread(new Runnable() {
                        @Override
                        public void run() {
                            System.out.println("[Thread-"+ Thread.currentThread().getId() +"]处理了"  + data[1]);
                        }
                    });
                    new Thread(mThread1).start();
                    new Thread(mThread2).start();
    
                }
            });
            t.start();
        }
    }
    
    class MThread implements Runnable {
    
        private Runnable r;
    
        public MThread(Runnable r) {
            this.r = r;
        }
    
        @Override
        public void run() {
            r.run();
        }
    }

    运行结果如下:

    一个请求有三个线程,如果有多个请求,运行结果如下:

    从日志中无法看出他们之间的所属关系(判断不出来他们是否是处理同一个request请求的)。如果某一个线程出现问题,我们也很难快速定位是哪个请求的处理结果。

     

    2. 代理实现日志追踪

    因此,我们使用MDC来在日志中增加traceId(同一个请求的多个线程拥有同一个traceId)。

    思路如下:

    1. 在request进来的时候, 利用AOP为每个request创建一个traceId(保证每个request的traceId不同, 同一个request的traceId相同)

    2. 创建子线程的时候, 将traceId通过动态代理的方式,传递到子线程中

     

    public class mainApp {
        public static void main(String[] args) {
            Runnable runnable = new Runnable() {
                @Override
                public void run() {
                    //AOP 生成一个traceId
                    MDC.put("traceId", UUID.randomUUID().toString().replace("-", ""));
                    //接收到一个request
                    System.out.println("[Thread-"+ Thread.currentThread().getId() +"]traceId["+ MDC.get("traceId") +"]开始发起请求");
                    String[] data = {"异常数据","基本数据"};
    
                    MThread mThread1 = new MThread(new Runnable() {
                        @Override
                        public void run() {
                            System.out.println("[Thread-"+ Thread.currentThread().getId() +"]traceId["+ MDC.get("traceId") +"]处理了" + data[0]);
                        }
                    }, MDC.getCopyOfContextMap());
                    MThread mThread2 = new MThread(new Runnable() {
                        @Override
                        public void run() {
                            System.out.println("[Thread-"+ Thread.currentThread().getId() +"]traceId["+ MDC.get("traceId") +"]处理了"  + data[1]);
                        }
                    }, MDC.getCopyOfContextMap());
                    new Thread(mThread1).start();
                    new Thread(mThread2).start();
    
                }
            };
            new Thread(runnable).start();
            new Thread(runnable).start();
        }
    }
    
    class MThread implements Runnable {
    
        private Runnable r;
    
        public MThread(Runnable r, Map<String, String> parentThreadMap) {
            LogProxy logProxy = new LogProxy(r, parentThreadMap);
            Runnable rProxy = (Runnable) Proxy.newProxyInstance(r.getClass().getClassLoader(), r.getClass().getInterfaces(), logProxy);
            this.r = rProxy;
        }
    
        @Override
        public void run() {
            r.run();
        }
    }
    
    //日志代理
    class LogProxy implements InvocationHandler {
    
        private Runnable r;
        private  Map<String, String> parentThreadMap;
    
        public LogProxy(Runnable r, Map<String, String> parentThreadMap) {
            this.r = r;
            this.parentThreadMap = parentThreadMap;
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            if (method.getName().equals("run")) {
                MDC.setContextMap(parentThreadMap);
            }
            return method.invoke(r, args);
        }
    }

     

    运行结果如下:

    两个请求, 同一个请求的traceId相同,不同请求的traceId不同。 完美实现多线程的日志追踪。

    实际WEB项目中,只需要在logback日志配置文件中,

    logging.pattern.console参数增[%X{traceId}]即可在LOGGER日志中打印traceId的信息。
    展开全文
  • 高效的多线程日志 功能需求 功能主要包括: 日志消息的级别: TRACE, DEBUG, INFO, WARN, ERROR, FATAL 日志消息有多个目的地(appender),如文件,socket, SMTP等 略 略 对于分布式系统中的服务进程而言,日志的...
  • 经常做线上问题排查的可能会有感受,由于日志打印一般是无序的,多线程下想要串行拿到一次请求中的相关日志简直是大海捞针。那么MDC是一种很好的解决办法。SLF4J的MDCSLF4J 提供了MDC ( Mapped Diagnostic Contexts ...
  • 最近在做项目时遇到一个很头疼的问题,我扩展了org.apache.log4j.DailyRollingFileAppender,用来实现日志名自定义,但出现了个很诡异的问题:日志第一次打印时打印一遍,第二次时同一...最近在做项目时遇到一个很...
  • 第五章 高效的多线程日志 日志有两种意思: 诊断日志 交易日志 本章讲的是前一种日志,文本的供人阅读的日志,通常用于故障诊断和追踪,也可用于性能分析。 日志通常要记录: 收到的每条消息的id...
  • 多线程日志

    2020-11-23 09:40:31
    本文参考自陈硕老师的muduo网络库,删减的繁多的依赖文件,精简如此,供更的人参考学习(感谢陈硕老师的muduo)。 copyable.h #ifndef MUDUO_BASE_COPYABLE_H #define MUDUO_BASE_COPYABLE_H namespace muduo ...
  • 基于socket epoll的高并发下多线程日志收集程序,可达到10000并发量而不丢失数据
  • 多线程日志记录源码

    2008-01-23 09:10:14
    VC 多线程线程安全日志记录源码
  • 支持串口日志抓取,简单写的,如果有问题,请评论提出。谢谢!
  • } } 使用起来也很简单,下面是我使用的一个例子,大概做的一个事情就是用这个executorService执行(提交)一个线程线程内部是一个死循环take一个阻塞队列,当get到内容后做我的业务,具体业务内容您可以忽略不看。...
  • 题目描述:先来分析一下这个题目,关于这16条日志记录,我们可以在主线程中产生出来,这没用什么难度,关键是开启4个线程去执行,现在有两种思路:一种是日志的产生和打印日志线程在逻辑上分开;一种是日志的产生...
  • logback多线程日志MDC

    2016-09-29 16:19:00
    MDC多线程记录日志 http://blog.csdn.net/sunzhenhua0608/article/details/29175283 转载于:https://www.cnblogs.com/userrain/p/5920308.html
  • 多线程日志输出 %t

    2020-06-22 15:59:46
    场景:多线程+logback logback配置日志格式: <property name="local.file.format" value="[%d{yyyy-MM-dd HH:mm:ss.SSS}] [${local.node.name}] [%X{traceId}] [%threadId] [%level] [%logger{36}:%-4line] - %...
  • 什么是日志?我也问过自己。字面意思,记录东西的。 之前面试的时候,面试官问过我,一般程序出了问题怎么调试。最常见的莫过于断点,或者我们在编程的时候条件判断响应的输出。但是这个东西在代码量小的时候是可以...
  • 基于slf4j实现多线程日志

    千次阅读 2018-02-04 15:36:13
    对于多线程的程序来说,排错是一件特别麻烦的事情,特别是针对日志多线程有可能发生日志写阻塞,那我们有没有可能每一个线程一个日志文件呢?答案是可以的,基于slf4j的MDC,具体MDC原理各位看官自行百度 直接...
  • C# 多线程日志写入

    千次阅读 2018-05-13 02:50:37
    1..net2.0支持方法来自:官方例子// This example shows a ReaderWriterLock protecting a shared // resource that is read concurrently and written exclusively // by multiple threads. // The complete code ...
  • 楼主最近刚刚接触python,还是个小菜鸟,没有学习python之前可以说楼主的shell...通过学习python,楼主有了一种想法,想法如下可不可以分割日志,把日志分割成很多的小块,利用多线程去分析日志,这个难点在哪,难...
  • //日志模块名、日志文件最大大小、滚动文件数量(日志的时候,当前文件重命名_1,_2,_3.再写新的文件) auto logger = spdlog::rotating_logger_mt("log", "log/Srio.txt", 2 * 1024 * 1024
  • C++支持多线程日志

    2010-11-22 17:23:49
    不会影响主线程的效率,因为日志是写到缓冲区中的
  • 在服务端编程中,日志是必不可少的,通常用于故障诊断和追踪,也可用于性能分析。在生产环境中应该做到 "Log Everything All The Time&...在多线程程序中,每个线程有自己的前端,整个程序共用一个后端。对于C...
  • 日志有两个意思:诊断日志(diagnostic log) 即 log4j、 logback、 slf4j、 glog、 g2log、 log4cxx、 log4cpp、 log4cplus、 Pantheios、 ezlogger 等 常用 日志 库 提供 的 日志 功能。交易 日志( transaction log)...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 6,207
精华内容 2,482
关键字:

多线程日志