XLog
Лёгкий, красивый, мощный и расширяемый Android и Java журнал, который может одновременно выводить журналы в Logcat, консоль и файл. Если вы хотите, вы можете вывести журналы куда угодно.
Зависимости
implementation 'com.elvishew:xlog:1.10.1'
Инициализация
XLog.init(LogLevel.ALL);
Вывод журнала
XLog.d("Привет xlog");
Выводит простое сообщение.
XLog.d(message);
Выводит сообщение с throwable
, обычно используется при возникновении исключения.
XLog.e(message, throwable);
Поддерживает форматирование строк, так что вам не нужно использовать +
для объединения большого количества строк и переменных.
XLog.d("Привет%s, мне %d лет", "Элвис", 20);
Неформатированные строки JSON и XML будут автоматически отформатированы.
XLog.json(JSON_CONTENT);
XLog.xml(XML_CONTENT);
Поддерживаются все типы данных Collection
и Map
.
XLog.d(array);
XLog.d(list);
XLog.d(map);
При необходимости вы также можете напрямую выводить объекты Intent
и Bundle
.
XLog.d(intent);
XLog.d(bundle);
Фактически, вы можете выводить любой тип объекта. Вы даже можете указать разные ObjectFormatter
для разных типов объектов, если не указано иное, при преобразовании объекта в строку будет непосредственно вызываться метод toString()
типа объекта.
XLog.d(object);
Обратите внимание: v/d/i/w/e
в вышеприведённом содержании можно заменять друг на друга, где v
означает VERBOSE
, d
означает DEBUG
, i
означает INFO
, w
означает WARNING
, а e
означает ERROR
.
xLog
обладает высокой расширяемостью, почти каждый компонент настраивается.
Во время инициализации вы можете использовать самый простой способ:
XLog.init(LogLevel.ALL);
Или вы можете использовать более продвинутый способ.
LogConfiguration config = new LogConfiguration.Builder()
.logLevel(BuildConfig.DEBUG ? LogLevel.ALL // Уровень журнала ниже этого уровня не будет выводиться, по умолчанию LogLevel.ALL
: LogLevel.NONE)
.tag("MY_TAG") // По умолчанию «X-LOG»
.enableThreadInfo() // Разрешить вывод информации о потоке, по умолчанию запрещено
.enableStackTrace(2) // Разрешить вывод стека вызовов глубиной 2, по умолчанию запрещено
.enableBorder() // Разрешить вывод рамки журнала, по умолчанию запрещено
.jsonFormatter(new MyJsonFormatter()) // Укажите форматтер JSON, по умолчанию DefaultJsonFormatter
.xmlFormatter(new MyXmlFormatter()) // Укажите форматтер XML, по умолчанию DefaultXmlFormatter
.throwableFormatter(new MyThrowableFormatter()) // Укажите форматтер исключений, по умолчанию DefaultThrowableFormatter
.threadFormatter(new MyThreadFormatter()) // Укажите форматер информации о потоках, по умолчанию DefaultThreadFormatter
.stackTraceFormatter(new MyStackTraceFormatter()) // Укажите форматер стека вызовов, по умолчанию DefaultStackTraceFormatter
.borderFormatter(new MyBoardFormatter()) // Укажите форматер рамки, по умолчанию DefaultBorderFormatter
.addObjectFormatter(AnyClass.class, // Добавить форматер объектов для указанного типа
new AnyClassObjectFormatter()) // По умолчанию используется Object.toString()
.addInterceptor(new BlacklistTagsFilterInterceptor( // Добавить фильтр чёрного списка тегов
"blacklist1", "blacklist2", "blacklist3"))
.addInterceptor(new MyInterceptor()) // Добавить перехватчик журналов
.build();
Printer androidPrinter = new AndroidPrinter(true); // Выводить журналы через android.util.Log
Printer consolePrinter = new ConsolePrinter(); // Выводить журналы в консоль через System.out
Printer filePrinter = new FilePrinter // Выводить журналы в файл
.Builder("<полный путь к каталогу журнала>") // Указать путь сохранения файла журнала
.fileNameGenerator(new DateFileNameGenerator()) // Указать генератор имени файла журнала, по умолчанию ChangelessFileNameGenerator("log")
.backupStrategy(new NeverBackupStrategy()) // Указать стратегию резервного копирования файлов журнала, по умолчанию FileSizeBackupStrategy(1024 * 1024)
.cleanStrategy(new FileLastModifiedCleanStrategy(MAX_TIME)) // Указать стратегию очистки файлов журнала, по умолчанию NeverCleanStrategy()
.flattener(new MyFlattener()) // Указать выравниватель журналов, по умолчанию DefaultFlattener
.writer(new MyWriter()) // Указать средство записи журналов, по умолчанию SimpleWriter
.build();
XLog.init( // Инициализировать XLog
config, // Использовать конфигурацию журнала, если она не указана, будет использоваться new LogConfiguration.Builder().build()
androidPrinter, // Добавить любое количество принтеров. Если принтер не добавлен, по умолчанию будет использоваться AndroidPrinter (Android)/ConsolePrinter (Java)
consolePrinter,
filePrinter);
После инициализации будет создан глобальный Logger
с глобальной конфигурацией, и все вызовы функций вывода XLog
будут переданы этому глобальному Logger
для вывода.
Кроме того, вы можете создать неограниченное количество Logger
ов с различными конфигурациями: На основе глобального Logger
можно изменить TAG на "TAG-A"
.
Logger logger = XLog.tag("TAG-A")
... // 其他配置的覆盖
.build();
logger.d("定制了 TAG 的消息");
На основе глобального Logger
можно разрешить печать журналов с рамкой и информацией о потоке.
Logger logger = XLog.enableBorder()
.enableThread()
... // 其他配置的覆盖
.build();
logger.d("带有线程信息和日志边框的消息");
Также можно использовать одноразовую конфигурацию для печати журналов.
XLog.tag("TAG-A").d("定制了 TAG 的消息");
XLog.enableBorder().enableThread().d("带有线程信息和日志边框的消息");
Можно печатать в любом месте.
Достаточно одной команды вызова:
XLog.d("你好 xlog");
чтобы напечатать "你好 xlog"
в:
AndroidPrinter
)FilePrinter
)
и в любом другом месте, куда вы хотите печатать.
Чтобы печатать в других местах, вам нужно только реализовать свой собственный интерфейс Printer
и указать его при инициализации.XLog.init(config, printer1, printer2...printerN);
или при создании неглобального Logger
:
Logger logger = XLog.printer(printer1, printer2...printerN)
.build();
или при одноразовой конфигурации печати:
XLog.printer(printer1, printer2...printerN).d("用一次性配置打印的消息");
Для сохранения журналов в файл необходимо создать FilePrinter
.
Printer filePrinter = new FilePrinter // 打印日志到文件的打印器
.Builder("<日志目录全路径>") // 指定保存日志文件的路径
.fileNameGenerator(new DateFileNameGenerator()) // 指定日志文件名生成器,默认为 ChangelessFileNameGenerator("log")
.backupStrategy(new NeverBackupStrategy()) // 指定日志文件备份策略,默认为 FileSizeBackupStrategy(1024 * 1024)
.cleanStrategy(new FileLastModifiedCleanStrategy(MAX_TIME)) // 指定日志文件清除策略,默认为 NeverCleanStrategy()
.flattener(new MyFlattener()) // 指定日志平铺器,默认为 DefaultFlattener
.build();
и добавить его при инициализации:
XLog.init(config, filePrinter);
или при создании неглобального Logger
:
Logger logger = XLog.printer(filePrinter)
... // other overrides
.build();
или при одноразовом вызове:
XLog.printer(filePrinter).d("用一次性配置打印的消息");
После настройки XLog
можно настроить LibCat
.
LibCat.config(true, filePrinter);
Затем журналы из сторонних библиотек/модулей (в том же приложении) также будут сохранены в файле.
Подробнее о LibCat
можно узнать здесь.
Вы можете напрямую указать имя файла или использовать некоторые правила для сохранения журналов в разных файлах.
ChangelessFileNameGenerator
, вы можете указать неизменное имя файла.日志目录
└──log
LevelFileNameGenerator
вы можете сохранять журналы в разные файлы в зависимости от уровня.日志目录
├──VERBOSE
├──DEBUG
├──INFO
├──WARN
└──ERROR
DateFileNameGenerator
, можно сохранять журналы в файлы по дате.日志目录
├──2020-01-01
├──2020-01-02
├──2020-01-03
└──2020-01-04
FileNameGenerator
для сохранения журналов по собственным правилам.日志目录
├──2020-01-01-<hash1>.log
├──2020-01-01-<hash2>.log
├──2020-01-03-<hash>.log
└──2020-01-05-<hash>.log
По умолчанию используется ChangelessFileNameGenerator
для хранения журналов в файле с именем log
.
Каждый элемент журнала (дата, время, уровень журнала и сообщение) перед сохранением в файл должен быть «сглажен» в одну строку. Для этого можно использовать Flattener
.
Мы уже определили PatternFlattener
, который может удовлетворить большинство ваших потребностей. Вам нужно только передать параметр pattern
.
Поддерживаются следующие параметры:
Параметр | Значение |
---|---|
{d} | Дата и время. Используется формат даты и времени по умолчанию "yyyy-MM-dd HH:mm:ss.SSS" |
{d format} | Дата и время. Использует пользовательский формат даты и времени |
{l} | Сокращение уровня журнала. Например: V/D/I |
{L} | Полное название уровня журнала. Например: VERBOSE/DEBUG/INFO |
{t} | TAG журнала |
{m} | Сообщение журнала |
Представьте себе журнал с уровнем DEBUG
, TAG "my_tag"
, сообщением "простое сообщение"
, используя разные pattern
, сглаженный журнал будет выглядеть так:
Pattern | Сглаженный журнал |
---|---|
{d} {l}/{t}: {m} | 2016-11-30 13:00:00.000 D/my_tag: простое сообщение |
{d yyyy-MM-dd HH:mm:ss.SSS} {l}/{t}: {m} | 2016-11-30 13:00:00.000 D/my_tag: простое сообщение |
{d yyyy/MM/dd HH:mm:ss} {l}|{t}: {m} | 2016/11/30 13:00:00 D|my_tag: простое сообщение |
{d yy/MM/dd HH:mm:ss} {l}|{t}: {m} | 16/11/30 13:00:00 D|my_tag: простое сообщение |
{d MM/dd HH:mm} {l}-{t}-{m} | 11/30 13:00 D-my_tag-простое сообщение |
Если вы не хотите указывать pattern
самостоятельно, можно использовать ClassicFlattener
. Он фактически является PatternFlattener
с параметром {d} {l}/{t}: {m}
.
По умолчанию FilePrinter
использует DefaultFlattener
, этот сглаживатель просто соединяет метку времени и сообщение, что вам, вероятно, не понравится, поэтому вы должны помнить, что нужно указать Flattener
, рекомендуется использовать ClassicFlattener
.
Со временем журналы могут стать очень большими, настолько большими, что мы не хотим их хранить. Используя AbstractBackupStrategy2
, мы можем помочь нам создать новый файл журнала с тем же именем в определённых условиях, а старый файл журнала будет иметь расширение .bak.n
(n — номер резервной копии). Этот процесс называется «резервное копирование журнала».
日志目录
├──log
├──log.bak.1
├──log.bak.2
├──log.bak.3
├──...
└──log.bak.n
Если вам не нравится расширение .bak.n
, вы можете напрямую использовать BackupStrategy2
для указания имени файла резервной копии.
В большинстве случаев вы просто хотите создать резервную копию, когда размер файла журнала достигает определённого размера. FileSizeBackupStrategy2
идеально подходит для этой задачи.
По умолчанию xLog
использует FileSizeBackupStrategy(1024*1024)
и создаёт резервную копию при достижении файлом журнала размера 1 Мбайт. Время срабатывания резервного копирования
При этом одновременно будет существовать только один файл, в который производится запись, и один файл резервной копии. Это означает, что вы можете сохранить максимум 2M журнала.
Поэтому, если вы хотите сохранить больше журналов и разрешить большее количество резервных копий (а не только одну по умолчанию), используйте FileSizeBackupStrategy2, который позволяет существовать нескольким файлам резервных копий одновременно.
Автоматическая очистка
Если вы используете FileNameGenerator, который генерирует имена файлов журналов, которые могут меняться, то в папке с журналами может быть более одного файла журнала, и их количество может увеличиваться. Кроме того, если вы также используете неограниченную стратегию резервного копирования, это также может привести к потере контроля над количеством журналов. Чтобы предотвратить переполнение диска, вам понадобится CleanStrategy.
Обычно вы можете использовать FileLastModifiedCleanStrategy, который автоматически удалит журналы, которые не были изменены в течение определённого периода времени (например, недели) во время инициализации.
По умолчанию используется NeverCleanStrategy, которая не выполняет автоматическую очистку.
Сжатие файлов журнала
Просто вызовите LogUtil.compress("<полный путь к каталогу журнала>", "<полный путь к сохранённому сжатому файлу>").
Будет создан zip-файл, и весь каталог журнала будет заархивирован и записан в него, чтобы вы могли легко собрать журналы пользователей для отладки проблем.
Обратите внимание: исходные файлы журналов не удаляются.
Перехват и фильтрация журналов
Используя Interceptor, у вас будет возможность изменить или отфильтровать журнал перед его печатью.
Вы можете использовать некоторые предопределённые Interceptors, такие как WhitelistTagsFilterInterceptor, который разрешает печать журналов с определёнными тегами, и BlacklistTagsFilterInterceptor, используемый для фильтрации журналов с определёнными тегами.
Для одного Logger можно указать несколько Interceptors. Эти Interceptors будут получать возможность изменять или фильтровать журналы в порядке их добавления. Если Interceptor фильтрует журнал, последующие Interceptors не получат возможности обработать этот журнал.
Форматирование объектов любого типа
Когда мы напрямую печатаем объект, например:
XLog.d(object);
по умолчанию будет вызван метод toString объекта.
Иногда реализация метода toString для объекта не соответствует вашим ожиданиям, поэтому вам нужен ObjectFormatter для определения того, как этот тип объекта должен быть преобразован в строку при печати.
На платформе Android мы определили IntentFormatter и BundleFormatter для типов Intent и Bundle.
Вы можете реализовать и добавить свой собственный ObjectFormatter для любого типа.
Следует отметить, что ObjectFormatter эффективен только при прямой печати объекта.
Аналогичные библиотеки
Сравнение с другими библиотеками журналов:
Совместимость
Чтобы обеспечить совместимость с Android Log, xLog поддерживает все методы Android Log.
Пожалуйста, посмотрите на класс Log, определённый в XLog.
Log.v(String, String);
Log.v(String, String, Throwable);
Log.d(String, String);
Log.d(String, String, Throwable);
Log.i(String, String);
Log.i(String, String, Throwable);
Log.w(String, String);
Log.w(String, String, Throwable);
Log.wtf(String, String);
Log.wtf(String, String, Throwable);
Log.e(String, String);
Log.e(String, String, Throwable);
Log.println(int, String, String);
Log.isLoggable(String, int);
Log.getStackTraceString(Throwable);
Миграция
Если у вас есть большой проект, использующий Android Log, и трудно заменить все использования Android Log на XLog, вы можете использовать совместимый API, просто заменив все 'android.util.Log' на 'com.elvishew.xlog.XLog.Log'.
(Для лучшей производительности старайтесь не использовать совместимые API).
Linux/Cygwin:
grep -rl "android.util.Log" <your-source-directory> | xargs sed -i "s/android.util.Log/com.elvishew.xlog.XLog.Log/g"
Mac:
grep -rl "android.util.Log" <your-source-directory> | xargs sed -i "" "s/android.util.Log/com.elvishew.xlog.XLog.Log/g"
Android Studio:
Существует ещё один способ замены всех 'android.util.Log', который заключается в использовании LibCat для перехвата всех журналов, напечатанных через android.util.Log, и перенаправления их на принтер XLog.
Проблемы
Если во время использования возникают какие-либо проблемы или есть предложения, создайте проблему. Перед созданием проблемы убедитесь, что аналогичная проблема уже не существует.
Третье лицо подробно
QQ группа обмена и помощи
Если после прочтения документации у вас всё ещё есть вопросы о том, как использовать, вы можете присоединиться к этой группе QQ для вопросов. Ответ на присоединение к группе — elvishew.
Лицензия
Copyright 2015-2021 Elvis Hew Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )