Ответ 1
Получил ответ
Он хранится в Поддержка библиотек/приложений/Iphone Simulator/# version no #/applications/# ваше приложение #/documents/logs/log-3hex no >
Я использую фреймворк cocoaLumberjack для регистрации в iOS. Для хранения журналов в файле я использовал этот код.
DDFileLogger* fileLogger = [[DDFileLogger alloc] init];
fileLogger.rollingFrequency = 60 * 60 * 24;
fileLogger.logFileManager.maximumNumberOfLogFiles = 7;
[DDLog addLogger:fileLogger];
DDLogVerbose(@"hello");
NSLog(@"hihihihihi");
Я не могу найти, где именно хранится файл журнала, сгенерированный этим кодом. Может ли кто-нибудь помочь мне с этой проблемой?
Получил ответ
Он хранится в Поддержка библиотек/приложений/Iphone Simulator/# version no #/applications/# ваше приложение #/documents/logs/log-3hex no >
В ответах здесь не говорится о том, что может быть несколько файлов журнала. Свойство 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];
}
}
Вы можете загружать файлы журнала с подключенного устройства или отправлять их напрямую из приложения. Оба подхода описаны ниже.
Напишите это в классе, где у вас есть ссылка на 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, заданный другим ответом.
Если вы хотите получить файлы журналов, созданные вашим приложением на устройстве,
/AppData/Library/Caches/Logs/
Приостановить голосование было бы неплохо, если бы это было полезно для вас!
Если вы используете 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
как для консоли, так и для файла.
Вы можете контролировать, где он хранится, например, я когда-нибудь сохранил его в папке 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];
Обнаружено, что это последнее:
DDFileLogger *fileLogger = [[DDFileLogger alloc] init];
fileLogger.logFileManager.logsDirectory;//THIS
Из официального кода:
Диспетчер файлов журнала по умолчанию.
Все файлы журналов помещаются в каталог logsDirectory. Если конкретный logsDirectory не указан, используется каталог по умолчанию. На Mac, это в ~/Library/Logs/. На iPhone это находится в ~/Library/Caches/Logs. Файлы журнала называются "log-.txt", где uuid является шестнадцатеричным шестнадцатеричным символом, состоящим из набора [0123456789ABCDEF]. Архивные файлы журналов автоматически удаляются в соответствии с свойством maximumNumberOfLogFiles.
Отправлять файлы журналов из приложения через электронную почту, 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
в файле Constants.
Constants.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>
Надеюсь, это поможет.