Где хранится файл журнала с использованиемcocoLumberjack

Я использую структуру ведения журнала CocoLumberjack для ведения журнала iOS. Для хранения логов в файле я использовал этот код.

DDFileLogger* fileLogger = [[DDFileLogger alloc] init];
fileLogger.rollingFrequency = 60 * 60 * 24; 
fileLogger.logFileManager.maximumNumberOfLogFiles = 7;

[DDLog addLogger:fileLogger];

DDLogVerbose(@"hello");
NSLog(@"hihihihihi");

Я не могу найти, где именно хранится файл журнала, созданный этим кодом. Может ли кто-нибудь помочь мне с этой проблемой?


person abhiasawa    schedule 20.06.2011    source источник
comment
fileLogger.logFileManager.logsDirectory   -  person Ravindranath Akila    schedule 18.02.2014


Ответы (9)


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

Отправка файлов журнала из приложения по электронной почте в Swift

Напишите это в классе, где у вас есть ссылка на DDFileLogger. Я бы поместил это в собственный класс регистратора, например. MyLogger.swift

var ddFileLogger: DDFileLogger!

var logFileDataArray: [NSData] {
    get {
        let logFilePaths = ddFileLogger.logFileManager.sortedLogFilePaths() as! [String]
        var logFileDataArray = [NSData]()
        for logFilePath in logFilePaths {
            let fileURL = NSURL(fileURLWithPath: logFilePath)
            if let logFileData = try? NSData(contentsOfURL: fileURL, options: NSDataReadingOptions.DataReadingMappedIfSafe) {
                // Insert at front to reverse the order, so that oldest logs appear first.
                logFileDataArray.insert(logFileData, atIndex: 0)
            }
        }
        return logFileDataArray
    }
}

Затем, когда пользователь нажимает кнопку, чтобы указать, что он хочет отправить журналы,

// Required by MFMailComposeViewController
import MessageUI

@IBAction func writeEmailTapped(sender: AnyObject) {
    if MFMailComposeViewController.canSendMail() {
        let composeVC = MFMailComposeViewController()
        composeVC.mailComposeDelegate = self

        // Configure the fields of the interface.
        composeVC.setToRecipients(["[email protected]"])
        composeVC.setSubject("Feedback for app")
        composeVC.setMessageBody("", isHTML: false)

        let attachmentData = NSMutableData()
        for logFileData in MyLogger.sharedInstance.logFileDataArray {
            attachmentData.appendData(logFileData)
        }
        composeVC.addAttachmentData(attachmentData, mimeType: "text/plain", fileName: "diagnostic.log")
        self.presentViewController(composeVC, animated: true, completion: nil)
    } else {
        // Tell user about not able to send email directly.
    }
}

Это приводит к появлению всплывающего окна для составления сообщения электронной почты с вложенным файлом с именем diagnostic.log, в котором объединены все файлы журналов.

Особая благодарность - это в значительной степени перевод Swift из версии Objective-C, данной другим ответом.

Получить файл(ы) журнала с устройства напрямую, через USB-кабель

Если вы хотите получить файлы журналов, созданные вашим приложением во время работы на устройстве,

  1. Подключите ваше устройство к вашему Mac
  2. В Xcode перейдите в «Окно» -> «Устройства».
  3. В левом верхнем углу списка устройств нажмите на подключенное устройство.
  4. На главной панели в разделе «Установленные приложения» щелкните приложение, в котором вы запустили CocoaLumberjack.
  5. В нижней части списка установленных приложений щелкните значок шестеренки, а затем выберите «Загрузить контейнер».
  6. В Finder щелкните правой кнопкой мыши (показать меню) сохраненный файл .xcappdata и выберите «Показать содержимое пакета».
  7. Файлы журнала сохраняются в /AppData/Library/Caches/Logs/

Было бы неплохо проголосовать, если это полезно для вас!

person Daniel    schedule 22.12.2012
comment
Просто и работает, мне интересно, можно ли получить журналы без использования Xcode? Иногда мне нужно, чтобы другие пользователи присылали мне логи - person xu huanze; 13.05.2013
comment
Я боюсь, что такая функция должна быть сделана на заказ, т.е. позволить пользователю нажать кнопку, чтобы отправить файлы по электронной почте или отправить через веб-службу. - person Daniel; 30.05.2013
comment
Как это можно обновить для XCode 7.1? Кажется, я больше не могу следовать этим шагам. edit: Разобрался Окно -> Устройства -> Загрузить контейнер для конкретного приложения. - person John Shelley; 26.10.2015
comment
Обновлен для Xcode 7.2 и добавлен код Swift, который отправляет ваши журналы по электронной почте. - person Daniel; 13.02.2016
comment
Убедитесь, что вы импортируете «import MessageUI» вверху. В противном случае вы получите ошибки. - person Jon_the_developer; 06.11.2017
comment
Я использую Xcode для загрузки контейнера и доступа к файлам журнала моего приложения iOS. Кто-нибудь знает, как это сделать для приложения watchOS? Я не могу найти способ загрузить контейнер приложения Apple Watch. - person Lextar; 20.12.2020

Ответы здесь, похоже, не учитывают тот факт, что может быть несколько файлов журнала. Вы можете использовать свойство logFileManager вашего экземпляра DDFileLogger для циклического просмотра информации о файле. Ознакомьтесь с общедоступными методами и свойствами в DDFileLogger.h. Следующее может быть полезным:

- (NSString *)logsDirectory;

- (NSArray *)unsortedLogFilePaths;
- (NSArray *)unsortedLogFileNames;
- (NSArray *)unsortedLogFileInfos;

- (NSArray *)sortedLogFilePaths;
- (NSArray *)sortedLogFileNames;
- (NSArray *)sortedLogFileInfos;

Вот мое решение для получения данных журнала (и их отправки по электронной почте). Обратите внимание, что на момент написания этой статьи количество файлов журнала по умолчанию равно 5.

- (NSMutableArray *)errorLogData {
    NSUInteger maximumLogFilesToReturn = MIN([KRLogManager sharedInstance].fileLogger.logFileManager.maximumNumberOfLogFiles, 10);
    NSMutableArray *errorLogFiles = [NSMutableArray arrayWithCapacity:maximumLogFilesToReturn];
    DDFileLogger *logger = [KRLogManager sharedInstance].fileLogger;
    NSArray *sortedLogFileInfos = [logger.logFileManager sortedLogFileInfos];
    for (int i = 0; i < MIN(sortedLogFileInfos.count, maximumLogFilesToReturn); i++) {
        DDLogFileInfo *logFileInfo = [sortedLogFileInfos objectAtIndex:i];
        NSData *fileData = [NSData dataWithContentsOfFile:logFileInfo.filePath];
        [errorLogFiles addObject:fileData];
    }
    return errorLogFiles;
}

- (void)composeEmailWithDebugAttachment {
    if ([MFMailComposeViewController canSendMail]) {

        MFMailComposeViewController *mailViewController = [[MFMailComposeViewController alloc] init];
        mailViewController.mailComposeDelegate = self;
        NSMutableData *errorLogData = [NSMutableData data];
        for (NSData *errorLogFileData in [self errorLogData]) {
            [errorLogData appendData:errorLogFileData];
        }
        [mailViewController addAttachmentData:errorLogData mimeType:@"text/plain" fileName:@"errorLog.txt"];
        [mailViewController setSubject:NSLocalizedString(@"Good Subject", @"")];
        [mailViewController setToRecipients:[NSArray arrayWithObject:@"[email protected]"]];

        [self presentModalViewController:mailViewController animated:YES];

    }

    else {
        NSString *message = NSLocalizedString(@"Sorry, your issue can't be reported right now. This is most likely because no mail accounts are set up on your mobile device.", @"");
        [[[UIAlertView alloc] initWithTitle:nil message:message delegate:nil cancelButtonTitle:NSLocalizedString(@"OK", @"") otherButtonTitles: nil] show];
    }
}
person Kyle Robson    schedule 18.07.2012
comment
Проблема вашего кода в том, что окончательный файл журнала не сортируется строго по времени. Вы можете пройти тест, чтобы узнать это. - person ikzjfr0; 27.10.2014
comment
Почему бы просто не установить logFileManager.maximumNumberOfLogFiles = 1? - person ikzjfr0; 27.10.2014
comment
@ikzjfr0 Вы можете настроить maxNumberOfLogFiles так, как хотите. По умолчанию максимальный размер файла журнала (на момент написания этой статьи) составляет 1 МБ. Если вы просто установите для параметра maxNumberOfLogFiles значение 1, то вы уменьшите количество журналов, на которые вы способны, на 1/5. Если вы установите максимальный размер файла в 5 МБ, вы вернетесь к тому, с чего начали. Я рад придерживаться значений по умолчанию, выбранных сопровождающим Cocoa Lumberjack, но вы вольны делать все, что хотите. Я ограничиваю метод электронной почты до 10 файлов журнала, чтобы сохранить разумный размер электронной почты. - person Kyle Robson; 28.10.2014
comment
меня больше всего беспокоит то, что файлы журналов не - person ikzjfr0; 29.10.2014
comment
где находится KRLogManager в дровосеке? - person Deepak Thakur; 14.12.2015
comment
@DeepakThakur извините за путаницу. KRLogManager не является частью Cocoa Lumberjack. Это то, что я использовал в прошлом, чтобы сохранить свой файловый регистратор. Есть несколько способов сделать это. Вы можете заменить [KRLogManager sharedInstance].fileLogger своим собственным экземпляром регистратора файлов. - person Kyle Robson; 14.12.2015
comment
примечание: presentModalViewController:(UIViewController *)modalViewController анимированный:(BOOL)анимированный устарел. Вместо этого используйте presentViewController:animated:completion:. - person tdios; 12.02.2016

Если вы используете CocoaLumberjack, у вас есть DDFileLogger.h, и вы можете предоставить уже реализованный метод currentLogFileInfo::

@interface DDFileLogger : DDAbstractLogger <DDLogger>
...
- (DDLogFileInfo *)currentLogFileInfo;
@end

Затем вы можете программно получить доступ к пути к текущему файлу с помощью:

// configure logger
DDFileLogger *fileLogger = [DDFileLogger new];
[DDLog addLogger:fileLogger];
[DDLog addLogger:[DDTTYLogger sharedInstance]];
DDLogInfo(@"log file at: %@", [[fileLogger currentLogFileInfo] filePath]);

Который на моем iPhone напечатал:

log file at: /var/mobile/Applications/3BE1219F-78BE-491C-B68C-74D6FA0C2EF1/Library/Caches/Logs/log-5D1286.txt

как в консоль, так и в файл.

person kenichi    schedule 10.07.2012
comment
Отличный ответ. Большое спасибо. Для этого нужно несколько голосов. - person braden; 10.09.2014

Вы можете контролировать, где он хранится, например, я иногда храню его в папке iTunes для быстрого поиска. Используйте это в AppDelegate при настройке fileLogger:

NSString * applicationDocumentsDirectory = [[[[NSFileManager defaultManager]    
     URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject] path];
DDLogFileManagerDefault *documentsFileManager = [[DDLogFileManagerDefault alloc]
     initWithLogsDirectory:applicationDocumentsDirectory];
DDFileLogger *fileLogger = [[DDFileLogger alloc]
     initWithLogFileManager:documentsFileManager];
person jpalten    schedule 28.09.2013
comment
Можем ли мы также изменить имя файла? - person Cintu; 08.11.2013
comment
Отлично - я был поражен, что это не то место, где оно хранилось по умолчанию! - person Peter Johnson; 11.10.2014

Обнаружил, что это последнее:

DDFileLogger *fileLogger = [[DDFileLogger alloc] init];

fileLogger.logFileManager.logsDirectory;//THIS

Из официального кода:

Файловый менеджер журнала по умолчанию.

Все файлы журналов размещаются внутри logsDirectory. Если конкретный logsDirectory не указан, используется каталог по умолчанию. На Mac это ~/Library/Logs/. На iPhone это ~/Library/Caches/Logs. Файлы журнала называются «log-.txt», где uuid — это 6-символьный шестнадцатеричный код, состоящий из набора [0123456789ABCDEF]. Архивные файлы журналов автоматически удаляются в соответствии со свойством maxNumberOfLogFiles.

person Ravindranath Akila    schedule 18.02.2014

Получил ответ

Он хранится в библиотеке/поддержке приложений/симуляторе iphone/#номер версии#/applications/#ваше приложение#/documents/logs/log-3hex no>

person abhiasawa    schedule 21.06.2011
comment
Как насчет доступа к нему на реальном устройстве iPhone? - person Sebastian Dwornik; 10.11.2011
comment
Кому-нибудь еще удалось извлечь сохраненные файлы журнала с устройства? - person Jonas Gardner; 11.04.2012
comment
На моем симуляторе я обнаружил, что журналы хранятся в ~/Library/Application Support/iPhone Simulator/#version no#/Applications/#your application uuid#/Library/Caches/Logs/log-#hex-no#>. - person Bryce Thomas; 14.08.2013
comment
Этот ответ для симулятора. Для журналов в устройстве следуйте ответу, который я дал ниже 22 декабря 2012 года. Не забудьте проголосовать, если это поможет! - person Daniel; 29.11.2013
comment
Попробуйте использовать iFunBox для проверки каталогов приложений на наличие файлов журналов. - person Ravindranath Akila; 18.02.2014
comment
Есть еще одно приложение под названием iExplorer. Можно и это использовать. - person Shane D; 02.09.2016

Отправлять файлы журнала из приложения по электронной почте в Objective-C

Код Objective-C:

В вашем заголовке:

#import <MessageUI/MessageUI.h>
#import "DDLog.h"
#import "DDFileLogger.h"

В вашей реализации:

- (NSMutableArray *)errorLogData {
    DDFileLogger *ddFileLogger = [DDFileLogger new];
    NSArray <NSString *> *logFilePaths = [ddFileLogger.logFileManager sortedLogFilePaths];
    NSMutableArray <NSData *> *logFileDataArray = [NSMutableArray new];
    for (NSString* logFilePath in logFilePaths) {
        NSURL *fileUrl = [NSURL fileURLWithPath:logFilePath];
        NSData *logFileData = [NSData dataWithContentsOfURL:fileUrl options:NSDataReadingMappedIfSafe error:nil];
        if (logFileData) {
            [logFileDataArray insertObject:logFileData atIndex:0];
        }
    }
    return logFileDataArray;
}

- (void)composeEmailWithDebugAttachment {
    if ([MFMailComposeViewController canSendMail]) {

        MFMailComposeViewController *mailViewController = [[MFMailComposeViewController alloc] init];
        mailViewController.mailComposeDelegate = self;
        NSMutableData *errorLogData = [NSMutableData data];
        for (NSData *errorLogFileData in [self errorLogData]) {
            [errorLogData appendData:errorLogFileData];
        }
        [mailViewController addAttachmentData:errorLogData mimeType:@"text/plain" fileName:@"filename.log"];
        [mailViewController setSubject:NSLocalizedString(@"LogFile Subject", @"")];
        [mailViewController setToRecipients:[NSArray arrayWithObject:@"[email protected]"]];

        [self presentViewController:mailViewController animated:YES completion:nil];

    } else {
        NSString *message = NSLocalizedString(@"Sorry, your issue can't be reported right now. This is most likely because no mail accounts are set up on your mobile device.", @"");
        [[[UIAlertView alloc] initWithTitle:nil message:message delegate:nil cancelButtonTitle:NSLocalizedString(@"OK", @"") otherButtonTitles: nil] show];
    }
}

- (void)mailComposeController:(MFMailComposeViewController *)mailer didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error {
    [self becomeFirstResponder];
    [mailer dismissViewControllerAnimated:YES completion:nil];
}

Вот как вы можете добавить что-то в свой лог-файл:

DDLogError(@"This is an error.");
DDLogWarn(@"This is a warning.");
DDLogInfo(@"This is just a message.");
DDLogVerbose(@"This is a verbose message.");

Не забудьте установить ddLogLevel в файле констант.

Константы.h:

extern NSUInteger const ddLogLevel;

Comstants.m:

NSUInteger const ddLogLevel =
#ifdef DEBUG
LOG_LEVEL_VERBOSE;
#else
LOG_LEVEL_ERROR;
#endif

Это очень очевидно, но не забудьте настроить CocoaLumberjack в файле AppDelegate.m.

[DDLog addLogger:[DDASLLogger sharedInstance]];
[DDLog addLogger:[DDTTYLogger sharedInstance]];

DDFileLogger *fileLogger = [[DDFileLogger alloc] init];
[fileLogger setMaximumFileSize:(1024 * 1024)];
[fileLogger setRollingFrequency:(3600.0 * 24.0)];
[[fileLogger logFileManager] setMaximumNumberOfLogFiles:7];
[DDLog addLogger:fileLogger];

Лучше всего вставить этот код в - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions; файла AppDelegate.m. Также вы должны добавить эту строку кода в заголовок AppDelegate.m:

#import <CocoaLumberjack/CocoaLumberjack.h>

Надеюсь, это поможет.

person Alexey Pelekh    schedule 04.10.2016

Мне пришлось немного переписать его, чтобы он был совместим со Swift 4...

var logFileDataArray: [Data] {
    let logFilePaths = delegate.fileLogger.logFileManager.sortedLogFilePaths
    var logFileDataArray = [Data]()
    for logFilePath in logFilePaths {
        let fileURL = URL(fileURLWithPath: logFilePath)
        if let logFileData =
            try? Data(contentsOf: fileURL, options: Data.ReadingOptions.mappedIfSafe) {
            logFileDataArray.insert(logFileData, at: 0)
        }
    }
    return logFileDataArray
}

func sendApplicationLog(text: String) {
    if MFMailComposeViewController.canSendMail() {
        let controller = MFMailComposeViewController()
        controller.mailComposeDelegate = self
        controller.setToRecipients(["[email protected]"])
        controller.setSubject("Log of motorkari iOS")
        controller.setMessageBody(text, isHTML: false)
        var attachmentData = Data()
        for logFileData in logFileDataArray { attachmentData.append(logFileData) }
        controller.addAttachmentData(attachmentData, mimeType: "text/plain",
                                    fileName: "motorkari_ios_application.log")
        present(controller, animated: true, completion: nil)
    } else {
        showMessage("Log cannot be send !")
    }
}
person Renetik    schedule 13.03.2019

Я не знаю, может ли это помочь кому-то еще... Я взял предыдущие ответы и передал их Swift 5. Помимо получения всех путей, он печатает содержимое.

let logFileLogger = DDFileLogger()
print(logFileLogger.logFileManager.logsDirectory)

for path in logFileLogger.logFileManager.sortedLogFilePaths {
    do {
        let content = try String(contentsOfFile: path, encoding: .utf8)
        print(content)
    } catch let error as NSError {
        print("Error: \(error.localizedDescription)")
    }
}
person TomCobo    schedule 02.04.2020