1%%-------------------------------------------------------------------- 2%% 3%% %CopyrightBegin% 4%% 5%% Copyright Ericsson AB 1999-2016. All Rights Reserved. 6%% 7%% Licensed under the Apache License, Version 2.0 (the "License"); 8%% you may not use this file except in compliance with the License. 9%% You may obtain a copy of the License at 10%% 11%% http://www.apache.org/licenses/LICENSE-2.0 12%% 13%% Unless required by applicable law or agreed to in writing, software 14%% distributed under the License is distributed on an "AS IS" BASIS, 15%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16%% See the License for the specific language governing permissions and 17%% limitations under the License. 18%% 19%% %CopyrightEnd% 20%% 21%% 22%%---------------------------------------------------------------------- 23%% File : etrap_logmgr.erl 24%% Purpose : Make it easier to use disk_log. 25%%---------------------------------------------------------------------- 26 27-module(etrap_logmgr). 28 29%%--------------- INCLUDES ----------------------------------- 30%% Local 31-include_lib("ETraP_Common.hrl"). 32%%--------------- IMPORTS------------------------------------- 33%%--------------- EXPORTS------------------------------------- 34-export([start/1, stop/1, log_safe/2, log_lazy/2, get_next/2]). 35 36 37%%------------------------------------------------------------ 38%% function : start 39%% Arguments: LogName - name of the disk_log. 40%% Returns : 41%% Effect : creating linked log 42%%------------------------------------------------------------ 43 44start(LogName) -> 45 case catch disk_log:open([{name, LogName}, 46 {file, LogName}, 47 {type, halt}, 48 {size, infinity}]) of 49 {ok, LogName} -> 50 ok; 51 {error, Reason} -> 52 ?tr_error_msg("Initiating internal log failed: ~p", [Reason]), 53 exit({error, Reason}); 54 {repaired, LogName, {recovered, _Rec}, {badbytes, _Bad}} -> 55 ok; 56 Other -> 57 ?tr_error_msg("Initiating internal log failed: ~p", [Other]), 58 exit({error, Other}) 59 end. 60 61%%------------------------------------------------------------ 62%% function : stop 63%% Arguments: LogName - name of the disk_log. 64%% Returns : 65%% Effect : 66%%------------------------------------------------------------ 67 68stop(LogName) -> 69 case catch disk_log:close(LogName) of 70 ok -> 71 ok; 72 {error, Reason} -> 73 ?tr_error_msg("Stopping internal log failed: ~p", [Reason]), 74 {error, Reason}; 75 Other -> 76 ?tr_error_msg("Stopping internal log failed: ~p", [Other]), 77 {error, Other} 78 end. 79 80 81%%------------------------------------------------------------ 82%% function : log_safe 83%% Arguments: LogName - name of the disk_log. If 'dummy' is 84%% used nothing should be logged. Reason, reuse code. 85%% LogRecord - record to store in the log. 86%% Returns : 87%% Effect : Writes a logrecord and synchronizes to make sure 88%% that the record is stored. 89%%------------------------------------------------------------ 90 91log_safe(dummy, _) -> 92 ok; 93log_safe(LogName, LogRecord) -> 94 case write_safe(LogName, LogRecord) of 95 ok -> 96 ok; 97 _ -> 98 %% We have to catch the exit because in some cases 99 %% it's not possible to abort action in the 2PC-protocol. 100 case catch start(LogName) of 101 ok -> 102 write_safe(LogName, LogRecord); 103 {'EXIT', Reason} -> 104 {error, Reason} 105 end 106 end. 107 108 109write_safe(LogName, LogRecord) -> 110 case catch disk_log:log(LogName, LogRecord) of 111 ok -> % wrote to kernel successfully 112 case catch disk_log:sync(LogName) of 113 ok -> % Written to disk successfully 114 ok; 115 {error, Reason} -> 116 ?tr_error_msg("Internal log write failed: ~p ~p", 117 [Reason, LogName]), 118 {error, Reason}; 119 Other -> 120 ?tr_error_msg("Internal log write failed: ~p ~p", 121 [Other, LogName]), 122 {error, Other} 123 end; 124 {error, Reason} -> 125 ?tr_error_msg("Internal log write failed: ~p ~p", [Reason, LogName]), 126 {error, Reason}; 127 Other -> 128 ?tr_error_msg("Internal log write failed: ~p ~p", [Other, LogName]), 129 {error, Other} 130 end. 131 132 133%%------------------------------------------------------------ 134%% function : log_lazy 135%% Arguments: LogName - name of the disk_log. If 'dummy' is 136%% used nothing should be logged. Reason, reuse code. 137%% LogRecord - record to store in the log. 138%% Returns : 139%% Effect : Writes a logrecord. The record may be lost. 140%%------------------------------------------------------------ 141 142log_lazy(dummy, _LogRecord) -> 143 ok; 144log_lazy(LogName, LogRecord) -> 145 case write_lazy(LogName, LogRecord) of 146 ok -> 147 ok; 148 _ -> 149 %% We have to catch the exit because in some cases 150 %% it's not possible to abort action in the 2PC-protocol. 151 case catch start(LogName) of 152 ok -> 153 write_lazy(LogName, LogRecord); 154 {'EXIT', Reason} -> 155 {error, Reason} 156 end 157 end. 158 159write_lazy(LogName, LogRecord) -> 160 case catch disk_log:log(LogName, LogRecord) of 161 ok -> 162 %% wrote to kernel successfully 163 ok; 164 {error, Reason} -> 165 %% Write to kernel failed with Reason 166 ?tr_error_msg("Internal log write failed: ~p", [Reason]), 167 {error, Reason}; 168 Other -> 169 %% unknown message received. 170 ?tr_error_msg("Internal log write failed: ~p", [Other]), 171 {error, Other} 172 end. 173 174 175%%------------------------------------------------------------ 176%% function : get_next 177%% Arguments: LogName - name of the disk_log. 178%% Cursor - place to read from. 179%% Returns : {Cursor, LogRecs} - A cursor and up to N logrecords. 180%% eof - the atom 'eof', indicating logfile empty. 181%% {error, Reason} - error. 182%% Effect : 183%% Purpose : Used when performing a REDO scan 184%%------------------------------------------------------------ 185 186get_next(LogName, Cursor) -> 187 case catch disk_log:chunk(LogName, Cursor, 1) of 188 {NewCursor, [Data]} -> 189 {Data, NewCursor}; 190 eof -> 191 eof; 192 {error, Reason} -> 193 ?tr_error_msg("Internal log '~p' read failed: ~p", 194 [LogName, Reason]), 195 exit({error, Reason}); 196 _Other -> 197 ?tr_error_msg("Internal log '~p' read failed: 'log_corrupt'", [LogName]), 198 exit({error, "log_corrupt"}) 199 end. 200 201%%--------------- END OF MODULE ------------------------------ 202