Last active
August 30, 2017 01:57
-
-
Save satoshin2071/9778283 to your computer and use it in GitHub Desktop.
[ObjcC] NSLogをコンソールとファイル両方に出力する
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import <Availability.h> | |
#ifndef __IPHONE_3_0 | |
#warning "This project uses features only available in iOS SDK 3.0 and later." | |
#endif | |
#ifdef __OBJC__ | |
#import <UIKit/UIKit.h> | |
#import <Foundation/Foundation.h> | |
#import "SBCLogUtil.h" | |
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import "SBCLogUtil.h" | |
#include <pthread.h> | |
@implementation SBCLogUtil | |
void SBCLog(NSString *format, ...) | |
{ | |
// ファイル名用formatter | |
NSDateFormatter *fileNameFormatter = [[NSDateFormatter alloc]init]; | |
fileNameFormatter.calendar = [[NSCalendar alloc]initWithCalendarIdentifier:NSGregorianCalendar]; | |
fileNameFormatter.locale = [NSLocale localeWithLocaleIdentifier:@"en_US"]; | |
[fileNameFormatter setDateFormat:@"yyyyMMdd"]; | |
// ログ時刻用formatter | |
NSDateFormatter *logFormatter = [[NSDateFormatter alloc]init]; | |
logFormatter.calendar = [[NSCalendar alloc]initWithCalendarIdentifier:NSGregorianCalendar]; | |
logFormatter.locale = [NSLocale localeWithLocaleIdentifier:@"en_US"]; | |
[logFormatter setDateFormat:@"yyyy-MM-dd hh:mm:ss.SSS"]; | |
NSString *createdDate = [fileNameFormatter stringFromDate:[NSDate date]]; | |
NSString *logDate = [logFormatter stringFromDate:[NSDate date]]; | |
// ファイルパス準備 | |
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, | |
NSUserDomainMask, | |
YES); | |
NSFileManager *fileManager = [NSFileManager defaultManager]; | |
NSString *filename = [NSString stringWithFormat:@"%@_log.txt",createdDate]; | |
NSString *documentsDirectory = [paths objectAtIndex:0]; | |
NSString *logDirctoryPath = [documentsDirectory stringByAppendingString:@"/logs"]; | |
if (![fileManager fileExistsAtPath:logDirctoryPath]) { | |
[fileManager createDirectoryAtPath:logDirctoryPath withIntermediateDirectories:YES attributes:nil error:nil]; | |
} | |
NSString *path = [logDirctoryPath stringByAppendingPathComponent:filename]; | |
static FILE *file = NULL; | |
if (file == NULL) { | |
// 一週間以上前のログあれば削除 | |
NSDate *todayDate = [NSDate date]; | |
NSArray *allFileNames = [fileManager contentsOfDirectoryAtPath:logDirctoryPath error:NULL]; | |
for(NSString *fileName in allFileNames){ | |
NSString *dateString = [fileName substringToIndex:8]; | |
NSDate *tmpDate = [fileNameFormatter dateFromString:dateString]; | |
NSTimeInterval since = [todayDate timeIntervalSinceDate:tmpDate]; | |
if( (int)((int)since / (60*60*24)) > 7 ){ | |
[fileManager removeItemAtPath:[NSString stringWithFormat:@"%@/%@",logDirctoryPath,fileName] error:NULL]; | |
} | |
} | |
// 書き込み用ファイルopen | |
file = fopen([path cStringUsingEncoding:NSASCIIStringEncoding], "a+"); | |
} | |
va_list args; | |
va_start(args, format); | |
// stderr にログを出す | |
NSLogv(format, args); | |
// ファイルにログを出す | |
// 末尾に改行なかったら入れる | |
if (![format hasSuffix:@"\n"]) { | |
format = [format stringByAppendingString:@"\n"]; | |
} | |
NSString *body = [[NSString alloc]initWithFormat:format arguments:args]; | |
// プロセスIDを取得 | |
NSProcessInfo *processInfo = [NSProcessInfo processInfo]; | |
int processID = [processInfo processIdentifier]; | |
// スレッドIDを収得 | |
mach_port_t machTID = pthread_mach_thread_np(pthread_self()); | |
// NSLogと同じ文章の形にする | |
NSString *log = [NSString stringWithFormat:@"%@ [%d:%x] %@",logDate, processID,machTID,body]; | |
fputs([log cStringUsingEncoding: NSUTF8StringEncoding],file); | |
fflush(file); | |
va_end(args); | |
} | |
} | |
@end |
すみません、ログに出力されるタイムスタンプが12時間表記になっていませんでしょうか。
私自身はプログラマではなくSEでして、その場限りのコードばかり書いる身なので非常に参考になりました。他の言語に触れた今にして思えば、C言語の奇妙な?staticの挙動を思い出しました。
ロジックの骨格はC言語で、ステートメントの大半がObjective-Cという想像していなかったコードに出会っておもしろかったです。(勝手にシングルトンのクラスを想像していたので...)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
NSLogと完全にすげ替えたいときはprefix.pchに下記defineで
define NSLog(...) SBCLog(VA_ARGS);