Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Добавление логов к сетевым запросам в Android
Логирование сетевых запросов — критически важная часть разработки, которая помогает в отладке, мониторинге API-взаимодействий и анализе проблем в production-среде. Рассмотрим несколько основных подходов в зависимости от используемых библиотек.
1. Использование Interceptor в OkHttp (рекомендуемый способ)
OkHttp предоставляет мощный механизм Interceptor для логирования. Вот как его настроить:
class LoggingInterceptor : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val request = chain.request()
val startTime = System.nanoTime()
// Логируем запрос
Log.d("NETWORK", "Запрос: ${request.method} ${request.url}")
request.headers.forEach { name, value ->
Log.d("NETWORK", "Заголовок: $name: $value")
}
// Продолжаем цепочку
val response = chain.proceed(request)
val endTime = System.nanoTime()
// Логируем ответ
Log.d("NETWORK", """
Ответ: ${response.code} ${response.message}
Время выполнения: ${(endTime - startTime) / 1_000_000} мс
URL: ${response.request.url}
""".trimIndent())
return response
}
}
// Настройка клиента
val client = OkHttpClient.Builder()
.addInterceptor(LoggingInterceptor())
.addNetworkInterceptor(LoggingInterceptor()) // Для сетевых логов
.build()
2. HttpLoggingInterceptor от Square
Библиотека logging-interceptor предоставляет готовое решение:
implementation 'com.squareup.okhttp3:logging-interceptor:4.12.0'
val loggingInterceptor = HttpLoggingInterceptor { message ->
Log.d("NETWORK", message)
}.apply {
level = HttpLoggingInterceptor.Level.BODY // Уровень детализации
}
val client = OkHttpClient.Builder()
.addInterceptor(loggingInterceptor)
.build()
// Уровни логирования:
// - NONE: без логов
// - BASIC: метод, URL, статус
// - HEADERS: заголовки
// - BODY: тело запроса/ответа
3. Логирование в Retrofit
При использовании Retrofit с OkHttp, интерсепторы добавляются аналогично:
val retrofit = Retrofit.Builder()
.baseUrl("https://api.example.com/")
.client(client) // Используем настроенный OkHttpClient
.addConverterFactory(GsonConverterFactory.create())
.build()
4. Улучшенное логирование с фильтрацией
Для production-приложений рекомендуется:
class SmartLoggingInterceptor(
private val isDebug: Boolean = BuildConfig.DEBUG
) : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
if (!isDebug) return chain.proceed(chain.request())
val request = chain.request()
// Маскируем чувствительные данные
val sanitizedHeaders = request.headers.mapValues { (key, value) ->
when (key.toLowerCase(Locale.ROOT)) {
"authorization", "api-key", "token" -> "***MASKED***"
else -> value
}
}
// Логируем безопасно
Timber.d("Запрос: %s %s", request.method, request.url)
sanitizedHeaders.forEach { Timber.d("%s: %s", it.key, it.value) }
return chain.proceed(request)
}
}
5. Библиотеки для продвинутого логирования
- Chucker: интерактивный интерсептор с UI
- Stetho: инструмент отладки от Facebook
- Timber: улучшенная обертка над Log
6. Production-рекомендации
Критические аспекты:
- Отключайте детальное логирование в production — используйте
BuildConfig.DEBUG - Маскируйте конфиденциальные данные: токены, пароли, персональные данные
- Логируйте в файл для последующего анализа проблем на устройствах пользователей
- Используйте разные уровни логирования: DEBUG для разработки, ERROR для критических сбоев
- Следите за производительностью: логирование не должно замедлять приложение
// Пример конфигурации для разных сборок
val loggingLevel = if (BuildConfig.DEBUG) {
HttpLoggingInterceptor.Level.BODY
} else {
HttpLoggingInterceptor.Level.NONE
}
7. Мониторинг и аналитика
Логи можно интегрировать с системами мониторинга:
- Логирование в Crashlytics/AppCenter для отслеживания сетевых ошибок
- Метрики времени ответа для анализа производительности API
- Статистика успешных/неуспешных запросов
Правильное логирование сетевых запросов значительно ускоряет отладку и помогает быстрее выявлять проблемы как на стороне клиента, так и на стороне сервера.