Published on

ARTS 第19周

Authors

这期各种日志相关。。。

Algorithm

937. Reorder Log Files

package org.nocoder.leetcode.solution;

import java.util.ArrayList;
import java.util.TreeMap;

/**
 * 937. Reorder Log Files
 *
 * You have an array of logs.  Each log is a space delimited string of words.
 *
 * For each log, the first word in each log is an alphanumeric identifier.  Then, either:
 *
 * Each word after the identifier will consist only of lowercase letters, or;
 * Each word after the identifier will consist only of digits.
 * We will call these two varieties of logs letter-logs and digit-logs.
 * It is guaranteed that each log has at least one word after its identifier.
 *
 * Reorder the logs so that all of the letter-logs come before any digit-log.
 *
 * The letter-logs are ordered lexicographically ignoring identifier,
 *
 * with the identifier used in case of ties.  The digit-logs should be put in their original order.
 *
 * Return the final order of the logs.
 *
 *
 * Example 1:
 *
 * Input: ["a1 9 2 3 1","g1 act car","zo4 4 7","ab1 off key dog","a8 act zoo"]
 * Output: ["g1 act car","a8 act zoo","ab1 off key dog","a1 9 2 3 1","zo4 4 7"]
 *
 *
 * Note:
 *
 * 0 <= logs.length <= 100
 * 3 <= logs[i].length <= 100
 * logs[i] is guaranteed to have an identifier, and a word after the identifier.
 *
 * @author jason
 * @date 2018/11/11.
 */
public class ReorderLogFiles {
    public static String[] reorderLogFiles(String[] logs) {
        ArrayList<String> list = new ArrayList<>();
        TreeMap<String, String> map = new TreeMap<>();

        for (String str: logs) {
            String[] tokens = str.split(" ");
            if (!Character.isAlphabetic(tokens[1].charAt(0))) {
                list.add(str);
            } else {
                String key = str.substring(tokens[0].length()).trim();
                map.put(key, str);
            }
        }

        String[] result = new String[logs.length];
        int i = 0;
        for (String key: map.keySet()) {
            result[i++] = map.get(key);
        }

        for (String str: list){
            result[i++] = str;
        }

        return result;
    }

    public static void main(String[] args) {
        String[] logs = new String[]{"a1 9 2 3 1", "g1 act car", "zo4 4 7", "ab1 off key dog", "a8 act zoo"};
        reorderLogFiles(logs);
    }
}

Review

30 best practices for logging at scale

一篇来自 Jason Skowronski 的文章,大规模记录日志的一些最佳实践,包括日志的创建,传输,以及日志的管理,我主要理解了一下创建日志的最佳做法。

  • 创建日志的最佳做法
    • 使用标准且易于配置的日志框架。
      • log4j,log4net等允许比硬编码或专有框架更快的配置更改。
    • 使用具有灵活输出选项的日志框架。
      • 查看控制台登录开发并集中prod日志,无需额外的插件或代理。
    • 使用像JSON这样的标准结构化格式。
      • 自定义格式和原始文本日志需要自定义解析规则来提取数据以进行分析。
    • Create a standard schema for your fields.(没理解)
      • Adding fields ad hoc can create a rat’s nest. A standard lets everyone know where to look.
    • 不要让日志记录阻止您的应用程序。
      • 使用缓冲区或队列异步写入日志,以便应用程序可以继续运行。
    • 注意平台即服务(PaaS)或基于容器的环境中的限制。
      • Heroku和Docker等环境对主机访问,syslog守护程序等设置了限制。
    • 为团队提供标准日志记录配置。

Tip

Ubuntu 启动界面修改

sudo update-alternatives --config default.plymouth
sudo update-initramfs -u

线程切换导致 Canal Message 乱序消费问题

这周遇到一个多线程问题,程序的一个BUG,Canal 要求顺序提交Message Batch Id,由于我在程序里使用了多线程进行提交 Canal Message Batch Id, 当线程切换时,会发生乱序提交的情况,于是 Canal Client 抛出 RuntimeException,导致主线程挂掉。解决办法就是把获取Message和提交BatchId改为同步执行,Ack操作之后,再开启新的线程处理Message。

Share

耗叔布置的"命题作文"

关于日志的那些事儿 整理了关于日志的一些内容,耗叔要求的【目标是一篇“引经据典“的,“全面系统“的对日志的介绍】。结合一些参考链接和以往的经验,主要对软件开发过程中日志相关的知识进行梳理和学习。