63

我正在使用 cocoaLumberjack 日志框架进行 iOS 日志记录。为了将日志存储在文件中,我使用了此代码。

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

[DDLog addLogger:fileLogger];

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

我无法找到此代码生成的日志文件的确切存储位置。有人可以帮我解决这个问题吗?

4

9 回答 9

74

您可以从连接的设备下载日志文件,也可以直接从应用程序发送。下面描述了这两种方法。

在 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(["your-email@company.com"])
        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,该文件是连接在一起的所有日志文件。

特别感谢 - 这几乎是另一个答案给出的 Objective-C 版本的 Swift 翻译。

通过 USB 电缆直接从设备获取日志文件

如果您想获取您的应用在设备上运行时创建的日志文件,

  1. 将您的设备连接到您的 Mac
  2. 在 Xcode 中,转到 Window -> Devices
  3. 在设备列表的左上角,单击已连接的设备。
  4. 在主面板的 Installed Apps 部分下,单击运行 CocoaLumberjack 的应用程序。
  5. 在已安装应用程序列表的底部,单击齿轮图标,然后单击下载容器。
  6. 在 Finder 中,右键单击(显示菜单)保存的 .xcappdata 文件并选择显示包内容
  7. 日志文件保存在/AppData/Library/Caches/Logs/

如果这对您有帮助,投票会很好!

于 2012-12-22T05:33:17.293 回答
65

这里的答案似乎没有考虑到可能有多个日志文件的事实。您可以使用 DDFileLogger 实例的 logFileManager 属性循环文件信息。查看 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:@"some@email.com"]];

        [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];
    }
}
于 2012-07-18T15:16:03.047 回答
32

如果您使用的是 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

到控制台和文件。

于 2012-07-10T19:45:07.577 回答
17

您可以控制它的存储位置,例如,我有时将它存储在 iTunes 文件夹中以便于检索。设置 fileLogger 时在 AppDelegate 中使用它:

NSString * applicationDocumentsDirectory = [[[[NSFileManager defaultManager]    
     URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject] path];
DDLogFileManagerDefault *documentsFileManager = [[DDLogFileManagerDefault alloc]
     initWithLogsDirectory:applicationDocumentsDirectory];
DDFileLogger *fileLogger = [[DDFileLogger alloc]
     initWithLogFileManager:documentsFileManager];
于 2013-09-28T09:27:51.240 回答
8

发现这是最新的:

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

fileLogger.logFileManager.logsDirectory;//THIS

来自官方代码:

默认日志文件管理器。

所有日志文件都放在logsDirectory 中。如果未指定特定的 logsDirectory,则使用默认目录。在 Mac 上,它位于 ~/Library/Logs/ 中。在 iPhone 上,它位于 ~/Library/Caches/Logs 中。日志文件被命名为“log-.txt”,其中 uuid 是由 [0123456789ABCDEF] 集合组成的 6 个字符的十六进制。根据 maximumNumberOfLogFiles 属性自动删除归档日志文件。

于 2014-02-18T07:20:30.357 回答
7

得到了答案

它存储在 Library/Appication Support/Iphone Simulator/#version no#/applications/#your application#/documents/logs/log-3hex no>

于 2011-06-21T08:44:12.103 回答
6

在 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@email.com"]];

        [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;

康斯坦茨.m:

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

这很明显,但不要忘记在AppDelegate.m文件中配置 CocoaLumberjack。

[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>

希望它会有所帮助。

于 2016-10-04T14:53:20.133 回答
1

我不得不稍微重写它以与 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(["dohan.rene@gmail.com"])
        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 !")
    }
}
于 2019-03-13T06:16:49.150 回答
1

我不知道这是否对其他人有帮助......我接受了以前的答案并将其传递给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)")
    }
}
于 2020-04-02T16:22:41.440 回答