Это 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, добро пожаловать в друзья для дальнейшего общения.