Не стоит недооценивать хвостовую команду, она поставила в тупик технического директора

Архитектура Linux

Это 200-я оригинальная статья xjjdog.

Оригинал: Miss Sister Taste (идентификатор публичной учетной записи WeChat: xjjdog), добро пожаловать, пожалуйста, сохраните источник для перепечатки.

Команда tail может видеть прокрутку лога, что очень удобно. тогдаxjjdogПодумайте, раз мы можем использовать эту команду для просмотра всех журналов, можем ли мы использовать команду tail для сбора журналов?

Воображение воображаемое, если вы хотите быстро实时Инструмент для сбора логов, этот хвост действительно отличный инструмент. Это намного быстрее, чем flume, logstatsh и filebeat. На самом деле, я делал это в старые времена, когда инструменты были в дефиците, и это работало нормально.

Ниже приведен фрагмент кода, написанный на языке Java. Мы можем читать журнал строка за строкой и делать все, что захотим, на нашем любимом языке.

import java.io.BufferedReader;
import java.io.InputStreamReader;

public class TailReader {
    public static void main(String[] args) throws Exception {
        ProcessBuilder ps = new ProcessBuilder("tail", "-f", "/tmp/tail0");
        //把错误输出也打印
        ps.redirectErrorStream(true);
        Process process = ps.start();

        //持续读取tail的输出
        try (BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
            String line;
            while ((line = in.readLine()) != null) {
                setLogToKafka(line);
                //注意这里不要产生异常,否则会打断while循环
            }
        }
    }

    //模拟发送到kafka,我们这里只简单的打印出来
    static void setLogToKafka(String line) {
        System.out.println(line);
    }
}

Основная идея состоит в том, чтобы использовать процесс Java для запуска дополнительного процесса и постоянного мониторинга вывода файла. Затем стандартный вывод и стандартные потоки ошибок направляются в BufferedReader. Далее вы можете делать все, что захотите.

Есть определенный риск, что если команда tail будет убита, наша Java-программа станет бесполезной.

Процедура простая, ноxjjdogЗдесь обсуждается не эта простая процедура сбора, аtailНекоторые интересные функции команды, вы можете увидеть специальную обработку файлов некоторыми инструментами сбора журналов.

Вы знаете разницу между хвостом -f и хвостом -F?

Прежде чем ответить на этот вопрос, давайте вспомним обработку логов, распространенный фреймворк логирования в Java.

<configuration>
  <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <!-- Support multiple-JVM writing to the same log file -->
    <prudent>true</prudent>
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
      <fileNamePattern>logFile.%d{yyyy-MM-dd}.log</fileNamePattern>
      <maxHistory>30</maxHistory> 
      <totalSizeCap>3GB</totalSizeCap>
    </rollingPolicy>

    <encoder>
      <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
    </encoder>
  </appender> 

  <root level="DEBUG">
    <appender-ref ref="FILE" />
  </root>
</configuration>

Вышеупомянутая конфигурация будет обновляться для формирования нового файла каждую ночь в ранние утренние часы.

Так как же работает этот свиток? Мы можем назвать это выходом, чтобы смоделировать процесс.

mv run.log run.2020-11-02.log
touch run.log

пройти тест

При прокрутке файла будут генерироваться новые файлы.Может ли команда tail все еще отслеживать это?

Давайте проверим это.

Первым шагом является создание файла для мониторинга

touch /tmp/tail0

Второй шаг, запустите наш Java-код

Третий шаг — сгенерировать непрерывный поток

watch -n 1  'echo `date` >> /tmp/tail0 '

Приведенная выше команда печатает текущую дату в наш файл каждую 1 секунду, и вы можете видеть, что сторона Java получила данные.

Четвертый шаг, имитация прокрутки файла

mv /tmp/tail0 /tmp/tail.bak
touch /tmp/tail0

На данный момент мы видим, что сторона Java больше не может получать данные.

Why?

Чтобы понять, почему, давайте посмотрим на некоторый статус процесса с помощью двух команд.

Сначала используйте команду ps для просмотра текущего хвостового процесса.

ps -ef|grep tail
  501 21374 21373   0  1:51PM ??         0:00.01 tail -f /tmp/tail0

Это точно наш заказ.

Мы используем команду lsof для просмотра файлов, связанных с этим процессом.

lsof -p 21374 | awk '{print $4 "\t"  $9}'
FD	NAME
cwd	/tmp/
txt	/usr/bin/tail
txt	/usr/lib/dyld
3r	/private/tmp/tail.bak

Мы видим, что файл, отслеживаемый процессом tail, на самом деле является файлом tail.bak, который не имеет ничего общего с командой tail.

Попробуем набрать что-то вроде tail.bak.

echo "haha: xjjdog, i am from tail.bak" >> /tmp/tail.bak

В это время, как мы и хотели, процесс Java ответил и вывел это предложение нормально.

что делать?

Как было задано в нашем вопросе, поместитеtail -fзаменитьtail -FВот и все.

tail -fСмысл в том, чтобы отслеживать по файловому дескриптору.

tail -FСмысл в том, что в соответствии с именем файла для отслеживания он повторит действие.

Итак, наш сборщик логов, который несомненно отслеживает по имени лога, должен поставитьfизменить наF.

End

Теперь, когда мы знаем эти небольшие различия, у нас есть объяснение некоторых паранормальных явлений, с которыми мы сталкиваемся в повседневной работе.

Всем известна команда rm, которая может удалить файл. Если есть этот файл, который используется другими процессами, похоже, вы удалили файл, но его содержимое не освобождается.

 lsof | grep deleted

Приведенная выше команда может видеть эти неуправляемые файлы. Как правило, когда вы уничтожаете соответствующий процесс, эти дескрипторы освобождаются. Но вы намерены удалить эти файлы, чтобы избежать перезапуска приложения, что действительно сбивает с толку.

 cat /dev/null > logpath

Поэтому, когда мы удаляем файлы, мы обычно используем не rm, а символ перенаправления. сделать все пустым/dev/null, им.

Об авторе:Мисс сестра вкус(xjjdog), публичная учетная запись, которая не позволяет программистам идти в обход. Сосредоточьтесь на инфраструктуре и Linux. Десять лет архитектуры, десятки миллиардов ежедневного трафика, обсуждение с вами мира высокой параллелизма, дающие вам другой вкус. Мой личный WeChat xjjdog0, добро пожаловать в друзья для дальнейшего общения.​