精华内容
下载资源
问答
  • 刚开始用 Python 做 web 开发的时候我就想一个问题,如果 Python 应用需要自己记录一些比 accesslog 更详细的日志(使用 Python 的 logging module),又有多个进程,怎么办最好... 最初没有设置日志的 rotation,起...

    刚开始用 Python 做 web 开发的时候我就想一个问题,如果 Python 应用需要自己记录一些比 accesslog 更详细的日志(使用 Python 的 logging module),又有多个进程,怎么办最好呢?多个进程往同一个日志文件写入会不会出问题?

    最近有个在 Apache 里用 mod_wsgi 运行的程序,设置了4个 process. 最初没有设置日志的 rotation,看起来一切正常。有一天设定了每天 midnight rotate(换成 TimedRotatingFileHandler), 第二天就出问题了,前一天的日志完全丢失,当天日志分散在前一天和当天的两个文件里,并且两个文件都在增长。比如今天是2011-08-14,现在去观察就会发现昨天的 customlog-20110813 和今天的 customlog 两个文件都在被写入。

    看了一下 TimedRotatingFileHandler 的 doRollover 方法:t = self.rolloverAt - self.interval

    if self.utc:

    timeTuple = time.gmtime(t)

    else:

    timeTuple = time.localtime(t)

    dfn = self.baseFilename + "." + time.strftime(self.suffix, timeTuple)

    if os.path.exists(dfn):

    os.remove(dfn)

    os.rename(self.baseFilename, dfn)

    ...

    这就了然了。每个进程在过了 rotate 时间点之后写第一条日志的时候,都会执行这个 doRollover,先看有没有 customlog-20110813 存在,存在的话删掉,把 customlog 改名为 customlog-20110813(注意这一步,文件名只是文件的一个属性,如果有进程已经打开该文件正在写入,并不会受影响,除非文件被删除),然后往新的 customlog 里写入。等四个进程都执行完这个方法的时候,就是一团糟了,不仅昨天的日志完全被删除,今天的日志也会有一小部分被删掉了。

    多进程 (Multiprocessing) vs. 多线程 (multithreading)

    假如只有一个进程,就不用操心这些了。我这个 qingbo.net 一直都是设置1个进程。于是我在 Stack Overflow 上问,如果 multithreading 就够了,为啥还要 multiprocessing 呢?回答者 Graham 好像是 mod_wsgi 的作者,从他的回答看,对于 Python 来说,由于 GIL 的限制,多进程才能利用多 CPU 或 core 的架构。

    好吧,想想有什么办法可以解决这个问题。

    Write separate files

    取得当前进程 ID (os.getpid()),然后把这个 pid 作为日志文件名的一部分,这样各个进程的日志操作就完全不会互相影响了。

    缺点是当服务器重启的时候,新的进程会有新的 pid,于是旧的文件不会被改成带有日期标识的名字,看起来不是那么干净。不过这个问题通过写一个简单的 shell 脚本即可修复,可以放在 crontab 里每天凌晨检查前一天的日志。

    结合 WatchedFileHandler 与 TimedRotatingFileHandler?

    以下是 WatchedFileHandler 的 emit 方法:def emit(self, record):

    """

    Emit a record.

    First check if the underlying file has changed, and if it

    has, close the old stream and reopen the file to get the

    current stream.

    """

    if not os.path.exists(self.baseFilename):

    stat = None

    changed = 1

    else:

    stat = os.stat(self.baseFilename)

    changed = (stat[ST_DEV] != self.dev) or (stat[ST_INO] != self.ino)

    if changed and self.stream is not None:

    self.stream.flush()

    self.stream.close()

    self.stream = self._open()

    if stat is None:

    stat = os.stat(self.baseFilename)

    self.dev, self.ino = stat[ST_DEV], stat[ST_INO]

    logging.FileHandler.emit(self, record)

    每写一条日志之前它先判断日志文件是不是被改名了,如果是的话就重新创建一个。如果 TimedRotatingFileHandler 在 doRollover 之前做这么一个检查,不就解决问题了吗?不过实际上这又牵扯到进程间同步的问题,还挺复杂的。

    WatchedFileHandler 结合 cron job

    一个取巧的办法是使用 WatchedFileHandler,并在 crontab 里每天零点添加一个任务,把日志文件改名。于是所有的进程在之后写第一条日志的时候会发现这一点,开始往新的文件里写入。

    我没有尝试这个办法所以不知到是不是有问题。但是它的前提是没一个写入操作是一个 atom operation,否则两条日志有可能混杂在一起,就坏了。我不太了解,不过这里有个讨论,看起来每条日志不超过 4K 的话是安全的。该文还展示了另一种办法――

    将日志发给一个独立的进程

    Python 的 logging module 还提供了一个 SocketHandler,用来把日志通过网络发送出去。文档里有一个非常基本的服务器端的实现。有人还基于 Twisted 写了一个更好的 logging server.

    但是这样我们除了需要维护 web server,又要维护 logging server. 万一 logging server 挂了怎么办?我有点担心。

    把日志发给 web server

    其实也是发给一个独立进程了。mod_wsgi 提供了一种途径,可以把 debug 信息写到 Apache 的 errorlog 里。不过把应用日志跟服务器 errorlog 混在一起,这显然不是什么好办法。

    比起多进程的解决方案,我更倾向于使用单线程省去这些烦恼。一方面是我的服务器比较弱,只有两个 core :) 正如 Graham 所说,除了 python code,还有许多处理比如接受、分发请求,发送响应回客户端,处理静态文件请求等都是在 Apache 的 C code里执行的,所以不会让一个 core 忙不过来另一个却闲着。我倒没有实际经验看看单个 Python 应用进程在4核或8核机器上面对大并发量的情况。

    单进程的另一个好处,可以不用 memcached 之类的东西,自己直接在进程的内存里方便地作缓存。如果有多个进程这么搞,那就太浪费内存了。

    展开全文
  • 前言log4js 算是“出镜率”很高的日志记录工具了...但在使用 PM2 开启 多线程 模式时,结果却不符合预期,比如:日志不输出、日志记录数据也有缺失。社区解决方案很详细,这里做个总结,同时讲下日志管理的相关事项...
    e65fc39ed9325839ddfad56c75d4af0d.png

    前言

    log4js 算是“出镜率”很高的日志记录工具了,如果你熟悉 java ,就会一第时间在 npm 中搜索到它。适用于大多数项目对日志需求(日志分级、按时间分割文件、按不同分类记录等…)。类似的还有 winston loglevel 等。

    但在使用 PM2 开启 多线程 模式时,结果却不符合预期,比如:日志不输出、日志记录数据也有缺失。

    社区解决方案很详细,这里做个总结,同时讲下日志管理的相关事项。

    先来看下 log4js 的基本配置

    如下配置对日志会有如下功能:

    • 未指定 categories 会有默认 default 的日志显示 appenders 输出,default 的日志级别为 debugger 及以上。
    • appenders 分为:控制台 console 输出、访问日志输出、错误异常输出。
    • 其中访问日志会按照日期进行分割。
    dc281d1a5faa28a51197246c52bde1a7.png

    正常运行项目后,日志输出正常,一切符合预期。(基于单进程方式)

    当遇到 PM2 时(cluster)

    为充分利用 cpu ,给应用开启多核能力,最方便莫过于使用 pm2 模块。具体使用不做赘述,简单使用,官网的文档足够了:

    https://pm2.keymetrics.io/docs/usage/pm2-doc-single-page/

    但开启多 cluster 后,log4js 日志却没有输出,不然也不会有那么多人苦恼了。

    配置修改

    log4js 相关:

    回到官网,看下有什么特殊配置,不过还得抱怨一下,log4js 的文档真的很“蛋疼”。

    https://log4js-node.github.io/log4js-node/api.html#configuration-object

    15061535f09c75f4cff3a300c4b1f017.png

    如上图,分别在 log4js 的配置里增加了:pm2、pm2InstanceVar 两个参数。

    pm2 配置相关:

    8e0ba13b0e726ff9cc20f1594b7a4f7f.png

    pm2 启动配置

    修改配置说明

    8edc35e792b39f0cca9fced31c8141a3.png

    设置 instance_var 实例变量,在交给 pm2 运行后,会自动赋值给 process.env.NODE_APP_INSTANCE 。详细说明可以看下官网说明:

    https://pm2.keymetrics.io/docs/usage/environment/#specific-environment-variables

    1c2d2ff36efe2c95f1e60e136d1d2c7b.png

    先结合 pm2 的 instance_var 配置,看下 log4js 的 pm2InstanceVar ,这两者必须设置的值相同。因为有关 isPM2Master 的逻辑判断:

    934e0b4d45d874be8ad6f888862cffd8.png

    再来具体看下 log4js 相关代码:

    efb45e1063425551fb5f2c50ea59dc36.png

    根据新增参数,预先移除原有的事件监听方式,当 isPM2Master 判断为 pm2 为主进程时,pm2-intercom 作为新的消息收发“中转站”。

    这就是为何配置了 log4js 的配置,但 没有安装 pm2-intercom ,就会发生日志不输出的情况。

    当然如果你图方便,在出现一些“未知错误”,可以尝试在 log4js 添加如下配置:

    disableClustering: true;

    它会使上面所说的方式失效,每个线程将会单独向目标日志文件输出内容,表明似乎问题可以解决,但是在高频访问下会出现日志缺失的情况。毕竟日志文件被多个进程写入放操作着。

    有效的日志管理

    对于一个线上的项目,可能需要一些其他手段来对日志做维护管理。既然现在说 pm2 ,就要看下其日志插件:pm2-logrotate

    来看下具体配置:

    6928b40f1d61b6972da623b365a01321.png

    定时轮询

    rotateIntervalworkerInterval 都有定时的作用。

    d3b9aa3b8c43e8036129547c79a7fee0.png

    前者通过编写 cron 表达式,约定每隔多少时间 强制 检查日志的状态。

    后者 workerInterval 是约定固定秒数来查询日志状况。(默认 30 秒)

    日志分割条件

    max_sizeretain 分别来约束日志的大小,和文件个数

    每次 定时轮询 触发后,会对文件大小,数量进行检查。超过约定的值,则会重新创建新文件。

    实际运用

    假设单日日志产出为 10G ,按照 rotateInterval 每天零点进行切割日志,虽然有章法,但如果要从 10G 大小的日志文件中排查问题,这似乎有些困难。

    我们可以设置 max_size 为 100M ,这样 10G 总大小的文件,将在一天中被切成 100 个。

    甚至如果每天的访问量有迹可循,比如上午 9-12 点会出现高峰,其他时间相对低频。可以进一步优化 workerInterval 和 rotateInterval cron 表达式:

    f4d6c046f8d5ebb167c4945329f5a74a.png

    这样在高访问时间段,可以跟有效的分割日志。(美中不足的是如果符合日志分割条件,00:00 和 00:30 时,会出现两份日志,强迫症表示不太适应)

    关于我

    一名工作在一线的前端工程师,乐于实践,并分享前端开发经验。

    关注头条号 or 微信公众号【前端雨爸】,欢迎评论留言,愿与各位交流进步。

    点击 ↙ 了解更多,了解更多前端开发技术文章。

    展开全文
  • 完多线程,毕老师讲到了2个线程之间轮流执行。但是怎么让3个多线程轮流执行呢? 下边让我们来分析一下代码。 JDK1.5中提供了多线程升级解决方案。 将同步synchronized替换成 实现LOCK操作 将Object 中的...

    <a href="http://edu.csdn.net/heima" target="blank">android培训</a>、<a href="http://edu.csdn.net/heima" target="blank">java培训</a>

    看完多线程,毕老师讲到了2个线程之间轮流执行。但是怎么让3个多线程轮流执行呢?

    下边让我们来分析一下代码。

    JDK1.5中提供了多线程升级解决方案。


    将同步synchronized替换成 实现LOCK操作

    将Object 中的wait,notify,notifyAll,替换成Condition对象

    该对象可以Lock锁,进行获取

    该示例中实现了本方只唤醒对方的操作



    import java.util.concurrent.locks.Condition;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;

    public class Workkk {
    public static void main(String[] args) {

    final HomeWorkee h = new HomeWorkee();
    new Thread() {
    public void run() {
    for (int i = 0; i < 3; i++)
    try {
    h.haha();
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }
    }.start();

    new Thread() {
    public void run() {
    for (int i = 0; i < 3; i++)
    try {
    h.hah();
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }
    }.start();

    new Thread() {
    public void run() {
    for (int i = 0; i < 3; i++)
    try {
    h.ha();
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }
    }.start();
    }

    }

    class HomeWorkee {
    private int x = 1;
    private int flag = 3; //标记为3,只能最先执行线程1


    private Lock lock = new ReentrantLock(); // 实现锁的接口
    /**
    * 定义3个Condition
    */
    private Condition condition_1 = lock.newCondition();
    private Condition condition_2 = lock.newCondition();
    private Condition condition_3 = lock.newCondition();

    public void hah()throws InterruptedException {
    lock.lock();
    try {
    if (flag == 1 ) {//线程1因为后边2个线程的短路判断,所以最先执行

    condition_1.await();//线程1等待
    }

    System.out.println("线程1:" + x++);
    System.out.println("线程1:" + x++);
    System.out.println("线程1:" + x++);
    System.out.println();

    flag = 1;//执行完以后把标记置为1
    condition_2.signal();//唤醒线程2
    }finally{
    lock.unlock();
    }
    }

    public void haha() throws InterruptedException{
    lock.lock();
    try {
    if (flag == 2 || flag == 3) {//因为flag初始值为3,所以即使线程抢到资源也不会执行,这样保证了线程按照顺序执行
    condition_2.await();
    }
    System.out.println("线程2:" + x++);
    System.out.println("线程2:" + x++);
    System.out.println("线程2:" + x++);
    System.out.println();
    flag = 2;//置为2
    condition_3.signal();//唤醒线程3

    } finally {
    lock.unlock();
    }
    }

    public void ha() throws InterruptedException {
    lock.lock();
    try {
    if (flag == 3 || flag == 1) {{//因为flag初始值为3,最先执行的1线程将标记改为2  所以即使线程抢到资源也不会执行,保证线程2优先线程3执行
    condition_3.await();

    }

    System.out.println("线程3:" + x++);
    System.out.println("线程3:" + x++);
    System.out.println("线程3:" + x++);
    System.out.println();

    flag = 3;
    condition_1.signal();//唤醒线程1
    }finally{
    lock.unlock();
    }
    }



    展开全文
  • 如果请求只在一个线程里处理,则我们可以通过线程ID来过滤日志,但如果请求包含异步线程的处理,那么光靠线程ID就显得捉襟见肘了。华为IoT平台,提供了接收设备上报数据的能力, 当数据到达平台后,平台会进行一些...

    前言

    在现网出现故障时,我们经常需要获取一次请求流程里的所有日志进行定位。如果请求只在一个线程里处理,则我们可以通过线程ID来过滤日志,但如果请求包含异步线程的处理,那么光靠线程ID就显得捉襟见肘了。

    华为IoT平台,提供了接收设备上报数据的能力, 当数据到达平台后,平台会进行一些复杂的业务逻辑处理,如数据存储,规则引擎,数据推送,命令下发等等。由于这个逻辑之间没有强耦合的关系,所以通常是异步处理。如何将一次数据上报请求中包含的所有业务日志快速过滤出来,就是本文要介绍的。

    正文

    SLF4J日志框架提供了一个MDC(Mapped Diagnostic Contexts)工具类,谷歌翻译为映射的诊断上下文,从字面上很难理解,我们可以先实战一把。

    public class Main { private static final String KEY = "requestId"; private static final Logger logger = LoggerFactory.getLogger(Main.class); public static void main(String[] args) { // 入口传入请求ID MDC.put(KEY, UUID.randomUUID().toString()); // 打印日志 logger.debug("log in main thread 1"); logger.debug("log in main thread 2"); logger.debug("log in main thread 3"); // 出口移除请求ID MDC.remove(KEY); }}

    我们在main函数的入口调用MDC.put()方法传入请求ID,在出口调用MDC.remove()方法移除请求ID。配置好log4j2.xml文件后,运行main函数,可以在控制台看到以下日志输出:

    2018-02-17 13:19:52.606 {requestId=f97ea0fb-2a43-40f4-a3e8-711f776857d0} [main] DEBUG cn.wudashan.Main - log in main thread 12018-02-17 13:19:52.609 {requestId=f97ea0fb-2a43-40f4-a3e8-711f776857d0} [main] DEBUG cn.wudashan.Main - log in main thread 22018-02-17 13:19:52.609 {requestId=f97ea0fb-2a43-40f4-a3e8-711f776857d0} [main] DEBUG cn.wudashan.Main - log in main thread 3

    从日志中可以明显地看到花括号中包含了(映射的)请求ID(requestId),这其实就是我们定位(诊断)问题的关键字(上下文)。有了MDC工具,只要在接口或切面植入put()和remove()代码,在现网定位问题时,我们就可以通过grep requestId=xxx *.log快速的过滤出某次请求的所有日志。

    进阶

    然而,MDC工具真的有我们所想的这么方便吗?回到我们开头,一次请求可能涉及多线程异步处理,那么在多线程异步的场景下,它是否还能正常运作呢?Talk is cheap, show me the code。

    public class Main { private static final String KEY = "requestId"; private static final Logger logger = LoggerFactory.getLogger(Main.class); public static void main(String[] args) { // 入口传入请求ID MDC.put(KEY, UUID.randomUUID().toString()); // 主线程打印日志 logger.debug("log in main thread"); // 异步线程打印日志 new Thread(new Runnable() { @Override public void run() { logger.debug("log in other thread"); } }).start(); // 出口移除请求ID MDC.remove(KEY); }}

    代码里我们新起了一个异步线程,并在匿名对象Runnable的run()方法打印日志。运行main函数,可以在控制台看到以下日志输出:

    2018-02-17 14:05:43.487 {requestId=e6099c85-72be-4986-8a28-de6bb2e52b01} [main] DEBUG cn.wudashan.Main - log in main thread2018-02-17 14:05:43.490 {} [Thread-1] DEBUG cn.wudashan.Main - log in other thread

    不幸的是,请求ID在异步线程里不打印了。这是怎么回事呢?要解决这个问题,我们就得知道MDC的实现原理。由于篇幅有限,这里就暂不详细介绍,MDC之所以在异步线程中不生效是因为底层采用ThreadLocal作为数据结构,我们调用MDC.put()方法传入的请求ID只在当前线程有效。感兴趣的小伙伴可以自己深入一下代码细节。

    知道了原理那么解决这个问题就轻而易举了,我们可以使用装饰器模式,新写一个MDCRunnable类对Runnable接口进行一层装饰。在创建MDCRunnable类时保存当前线程的MDC值,在执行run()方法时再将保存的MDC值拷贝到异步线程中去。代码实现如下:

    public class MDCRunnable implements Runnable { private final Runnable runnable; private final Map map; public MDCRunnable(Runnable runnable) { this.runnable = runnable; // 保存当前线程的MDC值 this.map = MDC.getCopyOfContextMap(); } @Override public void run() { // 传入已保存的MDC值 for (Map.Entry entry : map.entrySet()) { MDC.put(entry.getKey(), entry.getValue()); } // 装饰器模式,执行run方法 runnable.run(); // 移除已保存的MDC值 for (Map.Entry entry : map.entrySet()) { MDC.remove(entry.getKey()); } }}

    接着,我们需要对main函数里创建的Runnable实现类进行装饰:

    public class Main { private static final String KEY = "requestId"; private static final Logger logger = LoggerFactory.getLogger(Main.class); private static final ExecutorService EXECUTOR = Executors.newSingleThreadExecutor(); public static void main(String[] args) { // 入口传入请求ID MDC.put(KEY, UUID.randomUUID().toString()); // 主线程打印日志 logger.debug("log in main thread"); // 异步线程打印日志,用MDCRunnable装饰Runnable new Thread(new MDCRunnable(new Runnable() { @Override public void run() { logger.debug("log in other thread"); } })).start(); // 异步线程池打印日志,用MDCRunnable装饰Runnable EXECUTOR.execute(new MDCRunnable(new Runnable() { @Override public void run() { logger.debug("log in other thread pool"); } })); EXECUTOR.shutdown(); // 出口移除请求ID MDC.remove(KEY); }}

    执行main函数,将会输出以下日志:

    2018-03-04 23:44:05.343 {requestId=5ee2a117-e090-41d8-977b-cef5dea09d34} [main] DEBUG cn.wudashan.Main - log in main thread2018-03-04 23:44:05.346 {requestId=5ee2a117-e090-41d8-977b-cef5dea09d34} [Thread-1] DEBUG cn.wudashan.Main - log in other thread2018-03-04 23:44:05.347 {requestId=5ee2a117-e090-41d8-977b-cef5dea09d34} [pool-2-thread-1] DEBUG cn.wudashan.Main - log in other thread pool

    Congratulations!经过我们的努力,最终在异步线程和线程池中都有requestId打印了!

    总结

    本文讲述了如何使用MDC工具来快速过滤一次请求的所有日志,并通过装饰器模式使得MDC工具在异步线程里也能生效。有了MDC,再通过AOP技术对所有的切面植入requestId,就可以将整个系统的任意流程的日志过滤出来。使用MDC工具,在开发自测阶段,可以极大地节省定位问题的时间,提升开发效率;在运维维护阶段,可以快速地收集相关日志信息,加快分析速度。

    展开全文
  • 这里有17个G的日志文件,使用多线程压缩2分23秒即可压缩完成3.2G的压缩,6倍的压缩比,普通压缩则要使用7分50秒,整整多出了3倍,我们看看怎么使用的。 使用方法 安装pigz yum install pigz -y # 或者 apt-get ...
  • 问题描述: 在线程函数test()中 把::Sleep(100)去掉主函数就阻塞在threads.join_all()了, 加上就能顺利结束,这是什么原因呢。[img=https://forum.csdn.net/PointForum/ui/scripts/csdn/Plugin/003/onion/5.gif][/...
  • 继之前的mysql夺命连环之后,我发现我这个标题被好多套用的,什么夺命zookeeper,夺命多线程一大堆,这一次,开始面试题系列MQ专题,消息队列作为日常常见的使用中间件,面试也是必问的点之一,一起来看看MQ的面试题...
  • 因为日志会打印带上线程名称。所以联合起来可能会比较简单的排查问题吧。 怎么说。起始挺简单的。直接上代码,然后后续讲一下一些收获点。 /** 6 对应线程 展示 * */ @GetMapping("/f/threadMonitoring") @...
  • 异常信息作为我们平时定位...一个简单的例子首先我们看看如下的代码:这段代码非常的简单,创建一个线程池,实现一个Runnable,然后通过两种不同方式来执行这个它。代码很简单,那么它的运行结果是怎么样的呢?下...
  • 前言log4js 算是“出镜率”很高的日志记录工具了...但在使用 PM2 开启 多线程 模式时,结果却不符合预期,比如:日志不输出、日志记录数据也有缺失。社区解决方案很详细,这里做个总结,同时讲下日志管理的相关事项...
  • 经过跟踪是在打开OpenFileDialog时导致,由于此表单打开是调用另一个入口进入的,在打开后记录下日志发现:线程号是独立的。由此可以判断打开表单的是新线程。跟踪代码发现是使用BackgroundWorke...
  • 从输出日志看,是等待一个线程读取完毕再到一下个线程。请问怎么解决? 【2016-02-29 16:13:26】执行DBGridDataReaderV1d0.ReadData()函数共开销22.5003ms 【2016-02-29 16:13:26】执行DBGridDataReaderV1d0.Read...
  • 由于动态调试真的很麻烦,这个半个月基本都在代码和日志来分析程序。虽然经过了半个月,以现在对代码的熟悉程度,忽略gdb动态调试基本也问题不大。 但还是觉得很不舒服,很想在实际的多线程调试工作中,加入gdb这...
  • [已解决] 生产环境线程死锁造成的服务器无响应错误-线上问题定位与解决方案 文章目录概述问题定位根本原因解决总结 概述 最近团队有人遇到线程死锁的情况,在这里...首先,通过链路直接去机器上的日志,某几个方法请
  • org.apache.logging.log4j.core.async.AsyncLoggerConfigDisruptor以下所有源码均在此类中首先我们下log4j2异步队列的初始化 从这里面我们可以看到,使用的是单例的线程池,这里请注意,这个线程池里定义的是...
  • 问题来源:Youtube2016数据处理 下面简化后复现 RuntimeError: cannot join thread before it is started ...我看看怎么改。 这个问题先记着:点击日志中用户信息及最近点击item构成的多行数.
  • 重新思考不是查询语句和数据结构引起的慢查询,那为什么会偶发的超时,排查超时时间范围内的日志,并没有大量的突发请求,这让本来不精通ES的我雪上加霜!但是咱能怎么办,只能撸起袖子加油干!(我太难了)查询资料...
  • 本次踩坑springboot版本2.1.1 druid版本1.1.9 先讲下此次踩坑是怎么回事 项目本身为多数据源项目,第二数据源连接了一个只读db,...赶紧看日志,发现是该数据源的连接池直接满了。。 报错如下: ### Error q...
  • 大家帮忙下weblogic线程阻塞了 报错:which is more than the configured time (StuckThreadMaxTime) of "600" seconds. Stack trace: 但是不知道是怎么引起线程超时的,求解决方案。 另问吞吐率3.999正常吗,...
  • C++实现的一个简单的日志

    千次阅读 2017-05-07 00:58:50
    最近一直在《Linux多线程服务器编程》这本书。了里面实现的一个日志库功能,觉得很有意思。于是,就在2周前就准备开始模仿它实现。由于最近比较忙,直到今天才完成,其实也没怎么验证。毕竟只是作为自己学习之用...
  • android Log日志类实现

    2018-01-12 20:48:11
    一、StackTraceElement介绍: StackTraceElement 保存的是 运行轨迹栈,就是你在执行的时候,运行过的线程、类和方法的记录,而这个得到的方法可以通过: ...我们可以一下官方文档怎么说: f
  • 当我们在记录日志时,每个类中会定义... 其实我们可以这样,在要写日志的代码时获得当前的线程信息,这样我们就可以获得上个线程的信息了(即对象写日志所在类的信息)。  先以下列子。 新建Location类和Test
  • 系列文章—— ...上文《生产环境实践(二):Linux常用运维工具》带大家熟悉了各种性能分析工具,本篇则让我们看看之前获取到的JAVA进程堆栈数据怎么帮助我们排查生产线上问题的。 jstack命令保存java线程du
  • 1. Dump文件的用途Dump文件, 主要用于诊断一个进程的运行状态,尤其是碰到崩溃(Crash)或者挂起(hang)不响应时,需要分析它的工作状态. 除了平时常见的attach到这个进程, ... 然后,看看日志文件,也没有什么可用的信息
  • 1. Dump文件的用途 Dump文件, 主要用于诊断一个进程的运行状态,尤其是碰到崩溃(Crash)或者挂起(hang)不响应时,需要分析它的工作状态. 除了平时常见的attach到这个进程, ... 然后,看看日志文件,也没有什么可用的...

空空如也

空空如也

1 2 3 4 5 ... 7
收藏数 124
精华内容 49
关键字:

日志怎么看线程