|
|
@ -1,21 +1,24 @@ |
|
|
|
-module(rumRotatorIns). |
|
|
|
|
|
|
|
-include_lib("kernel/include/file.hrl"). |
|
|
|
|
|
|
|
-behaviour(rumRotatorExm). |
|
|
|
|
|
|
|
-include_lib("kernel/include/file.hrl"). |
|
|
|
|
|
|
|
-export([ |
|
|
|
create_logfile/2, open_logfile/2, ensure_logfile/5, rotate_logfile/2 |
|
|
|
createLogFile/2 |
|
|
|
, openLogFile/2 |
|
|
|
, ensureLogFile/5 |
|
|
|
, rotateLogFile/2 |
|
|
|
]). |
|
|
|
|
|
|
|
-ifdef(TEST). |
|
|
|
-include_lib("eunit/include/eunit.hrl"). |
|
|
|
-endif. |
|
|
|
|
|
|
|
create_logfile(Name, Buffer) -> |
|
|
|
open_logfile(Name, Buffer). |
|
|
|
createLogFile(Name, Buffer) -> |
|
|
|
openLogFile(Name, Buffer). |
|
|
|
|
|
|
|
open_logfile(Name, Buffer) -> |
|
|
|
openLogFile(Name, Buffer) -> |
|
|
|
case filelib:ensure_dir(Name) of |
|
|
|
ok -> |
|
|
|
Options = [append, raw] ++ |
|
|
@ -29,9 +32,9 @@ open_logfile(Name, Buffer) -> |
|
|
|
case file:read_file_info(Name, [raw]) of |
|
|
|
{ok, FInfo0} -> |
|
|
|
Inode = FInfo0#file_info.inode, |
|
|
|
{ok, Ctime} = maybe_update_ctime(Name, FInfo0), |
|
|
|
{ok, CTime} = maybe_update_ctime(Name, FInfo0), |
|
|
|
Size1 = FInfo0#file_info.size, |
|
|
|
{ok, {FD, Inode, Ctime, Size1}}; |
|
|
|
{ok, {FD, Inode, CTime, Size1}}; |
|
|
|
X -> X |
|
|
|
end; |
|
|
|
Y -> Y |
|
|
@ -39,14 +42,14 @@ open_logfile(Name, Buffer) -> |
|
|
|
Z -> Z |
|
|
|
end. |
|
|
|
|
|
|
|
ensure_logfile(Name, undefined, _Inode, _Ctime, Buffer) -> |
|
|
|
open_logfile(Name, Buffer); |
|
|
|
ensure_logfile(Name, FD, Inode0, Ctime0, Buffer) -> |
|
|
|
case rumUtil:has_file_changed(Name, Inode0, Ctime0) of |
|
|
|
ensureLogFile(Name, undefined, _Inode, _CTime, Buffer) -> |
|
|
|
openLogFile(Name, Buffer); |
|
|
|
ensureLogFile(Name, FD, Inode0, CTime0, Buffer) -> |
|
|
|
case rumUtil:has_file_changed(Name, Inode0, CTime0) of |
|
|
|
{true, _FInfo} -> |
|
|
|
reopen_logfile(Name, FD, Buffer); |
|
|
|
{_, FInfo} -> |
|
|
|
{ok, {FD, Inode0, Ctime0, FInfo#file_info.size}} |
|
|
|
{ok, {FD, Inode0, CTime0, FInfo#file_info.size}} |
|
|
|
end. |
|
|
|
|
|
|
|
reopen_logfile(Name, FD0, Buffer) -> |
|
|
@ -55,8 +58,8 @@ reopen_logfile(Name, FD0, Buffer) -> |
|
|
|
_ = file:datasync(FD0), |
|
|
|
_ = file:close(FD0), |
|
|
|
_ = file:close(FD0), |
|
|
|
case open_logfile(Name, Buffer) of |
|
|
|
{ok, {_FD1, _Inode, _Size, _Ctime} = FileInfo} -> |
|
|
|
case openLogFile(Name, Buffer) of |
|
|
|
{ok, {_FD1, _Inode, _Size, _CTime} = FileInfo} -> |
|
|
|
%% inode changed, file was probably moved and |
|
|
|
%% recreated |
|
|
|
{ok, FileInfo}; |
|
|
@ -65,26 +68,26 @@ reopen_logfile(Name, FD0, Buffer) -> |
|
|
|
end. |
|
|
|
|
|
|
|
%% renames failing are OK |
|
|
|
rotate_logfile(File, 0) -> |
|
|
|
rotateLogFile(File, 0) -> |
|
|
|
%% open the file in write-only mode to truncate/create it |
|
|
|
case file:open(File, [write]) of |
|
|
|
{ok, FD} -> |
|
|
|
_ = file:close(FD), |
|
|
|
_ = file:close(FD), |
|
|
|
{ok, _Ctime} = maybe_update_ctime(File), |
|
|
|
{ok, _CTime} = maybe_update_ctime(File), |
|
|
|
ok; |
|
|
|
Error -> |
|
|
|
Error |
|
|
|
end; |
|
|
|
rotate_logfile(File0, 1) -> |
|
|
|
rotateLogFile(File0, 1) -> |
|
|
|
File1 = File0 ++ ".0", |
|
|
|
_ = file:rename(File0, File1), |
|
|
|
rotate_logfile(File0, 0); |
|
|
|
rotate_logfile(File0, Count) -> |
|
|
|
rotateLogFile(File0, 0); |
|
|
|
rotateLogFile(File0, Count) -> |
|
|
|
File1 = File0 ++ "." ++ integer_to_list(Count - 2), |
|
|
|
File2 = File0 ++ "." ++ integer_to_list(Count - 1), |
|
|
|
_ = file:rename(File1, File2), |
|
|
|
rotate_logfile(File0, Count - 1). |
|
|
|
rotateLogFile(File0, Count - 1). |
|
|
|
|
|
|
|
maybe_update_ctime(Name) -> |
|
|
|
case file:read_file_info(Name, [raw]) of |
|
|
@ -130,7 +133,7 @@ rotate_file_test() -> |
|
|
|
% creates the file that Inner looks for. |
|
|
|
% Don't shoot the messenger, it was worse before this refactoring. |
|
|
|
lists:foreach(Inner, lists:seq(0, Count - 1)), |
|
|
|
rotate_logfile(TestLog, RotCount) |
|
|
|
rotateLogFile(TestLog, RotCount) |
|
|
|
end, |
|
|
|
lists:foreach(Outer, lists:seq(0, (RotCount * 2))), |
|
|
|
rumUtil:delete_test_dir(TestDir). |
|
|
@ -139,7 +142,7 @@ rotate_file_zero_count_test() -> |
|
|
|
%% Test that a rotation count of 0 simply truncates the file |
|
|
|
{ok, TestDir} = rumUtil:create_test_dir(), |
|
|
|
TestLog = filename:join(TestDir, "rotation.log"), |
|
|
|
?assertMatch(ok, rotate_logfile(TestLog, 0)), |
|
|
|
?assertMatch(ok, rotateLogFile(TestLog, 0)), |
|
|
|
?assertNot(filelib:is_regular(TestLog ++ ".0")), |
|
|
|
?assertEqual(true, filelib:is_regular(TestLog)), |
|
|
|
?assertEqual(1, length(filelib:wildcard(TestLog ++ "*"))), |
|
|
@ -167,7 +170,7 @@ rotate_file_fail_test() -> |
|
|
|
_ -> |
|
|
|
%% hose up the permissions |
|
|
|
ok = rumUtil:set_dir_permissions("u-w", TestDir), |
|
|
|
?assertMatch({error, _}, rotate_logfile(TestLog, 10)) |
|
|
|
?assertMatch({error, _}, rotateLogFile(TestLog, 10)) |
|
|
|
end, |
|
|
|
|
|
|
|
%% check we still only have one file, rotation.log |
|
|
@ -177,7 +180,7 @@ rotate_file_fail_test() -> |
|
|
|
%% fix the permissions |
|
|
|
ok = rumUtil:set_dir_permissions("u+w", TestDir), |
|
|
|
|
|
|
|
?assertMatch(ok, rotate_logfile(TestLog, 10)), |
|
|
|
?assertMatch(ok, rotateLogFile(TestLog, 10)), |
|
|
|
?assert(filelib:is_regular(TestLog ++ ".0")), |
|
|
|
?assertEqual(true, filelib:is_regular(TestLog)), |
|
|
|
?assertEqual(2, length(filelib:wildcard(TestLog ++ "*"))), |
|
|
|