GnuCash c935c2f+
Loading...
Searching...
No Matches
Files | Functions

The transaction logging mechanism provides a very simple, low-level logging of user input to a file. More...

Files

file  TransLog.h
 API for the transaction logger.
 

Functions

void xaccOpenLog (void)
 
void xaccCloseLog (void)
 
void xaccReopenLog (void)
 
void xaccTransWriteLog (Transaction *trans, char flag)
 
void xaccLogEnable (void)
 document me
 
void xaccLogDisable (void)
 document me
 
void xaccLogSetBaseName (const char *)
 The xaccLogSetBaseName() method sets the base filepath and the root part of the journal file name.
 
gboolean xaccFileIsCurrentLog (const gchar *name)
 Test a filename to see if it is the name of the current logfile.
 

Detailed Description

The transaction logging mechanism provides a very simple, low-level logging of user input to a file.

The goal of the transaction logger is to provide mechanism of last resort for recovering lost user data in the event of a crash.

Ideally, the storage backends should provide a robust journaling, logging and crash-recovery mechanism. But just in case they don't, or it didn't work, this mechanism provides a "Plan B" by providing a low-tech, fool-proof, simple logging system that can be used to recover user input. There are some simple command-line tools that will read a log and replay it.

Function Documentation

◆ xaccCloseLog()

void xaccCloseLog ( void  )

Definition at line 211 of file TransLog.cpp.

212{
213 if (!trans_log_stream.is_open()) return;
214 trans_log_stream.flush();
215 trans_log_stream.close();
216}

◆ xaccFileIsCurrentLog()

gboolean xaccFileIsCurrentLog ( const gchar *  name)

Test a filename to see if it is the name of the current logfile.

Definition at line 141 of file TransLog.cpp.

142{
143 gchar *base;
144
145 if (!name || trans_log_name.empty())
146 return FALSE;
147
148 base = g_path_get_basename(name);
149 bool result = trans_log_name.compare(base) == 0;
150 g_free(base);
151 return result;
152}

◆ xaccLogDisable()

void xaccLogDisable ( void  )

document me

Definition at line 96 of file TransLog.cpp.

97{
98 gen_logs = 0;
99}

◆ xaccLogEnable()

void xaccLogEnable ( void  )

document me

Definition at line 100 of file TransLog.cpp.

101{
102 gen_logs = 1;
103}

◆ xaccLogSetBaseName()

void xaccLogSetBaseName ( const char *  basepath)

The xaccLogSetBaseName() method sets the base filepath and the root part of the journal file name.

If the journal file is already open, it will close it and reopen it with the new base name.

Definition at line 120 of file TransLog.cpp.

121{
122 if (!basepath) return;
123
124 log_base_name = basepath;
125
126 if (trans_log_stream.is_open())
127 {
128 xaccCloseLog();
129 xaccOpenLog();
130 }
131}

◆ xaccOpenLog()

void xaccOpenLog ( void  )

Definition at line 158 of file TransLog.cpp.

159{
160 char * filename;
161 char * timestamp;
162
163 if (!gen_logs)
164 {
165 PINFO ("Attempt to open disabled transaction log");
166 return;
167 }
168 if (trans_log_stream.is_open()) return;
169
170 if (log_base_name.empty())
171 log_base_name = "translog";
172
173 /* tag each filename with a timestamp */
174 timestamp = gnc_date_timestamp ();
175
176 filename = g_strconcat (log_base_name.c_str(), ".", timestamp, ".log", nullptr);
177
178 trans_log_stream.open(filename, std::ios::app);
179 if (!trans_log_stream.is_open())
180 {
181 int norr = errno;
182 printf ("Error: xaccOpenLog(): cannot open journal\n"
183 "\t %d %s\n", norr, g_strerror (norr) ? g_strerror (norr) : "");
184
185 g_free (filename);
186 g_free (timestamp);
187 return;
188 }
189
190 /* Save the log file name */
191 auto tmpstr = g_path_get_basename(filename);
192 trans_log_name = tmpstr;
193 g_free (tmpstr);
194
195 g_free (filename);
196 g_free (timestamp);
197
198 /* Note: this must match src/import-export/log-replay/gnc-log-replay.c */
199 trans_log_stream << "mod\ttrans_guid\tsplit_guid\ttime_now\t"
200 << "date_entered\tdate_posted\t"
201 << "acc_guid\tacc_name\tnum\tdescription\t"
202 << "notes\tmemo\taction\treconciled\t"
203 << "amount\tvalue\tdate_reconciled\n"
204 << "-----------------\n";
205}
gchar * gnc_date_timestamp(void)
Make a timestamp in YYYYMMDDHHMMSS format.
#define PINFO(format, args...)
Print an informational note.
Definition qoflog.h:256

◆ xaccReopenLog()

void xaccReopenLog ( void  )

Definition at line 109 of file TransLog.cpp.

110{
111 if (trans_log_stream.is_open())
112 {
113 xaccCloseLog();
114 xaccOpenLog();
115 }
116}

◆ xaccTransWriteLog()

void xaccTransWriteLog ( Transaction *  trans,
char  flag 
)
Parameters
transThe transaction to write out to the log
flagThe engine currently uses the log mechanism with flag char set as follows: 'B' for 'begin edit' (followed by the transaction as it looks before any changes, i.e. the 'old value') 'D' for delete (i.e. delete the previous B; echoes the data in the 'old B') 'C' for commit (i.e. accept a previous B; data that follows is the 'new value') 'R' for rollback (i.e. revert to previous B; data that follows should be identical to old B)

Definition at line 222 of file TransLog.cpp.

223{
224 GList *node;
225 char trans_guid_str[GUID_ENCODING_LENGTH + 1];
226 char split_guid_str[GUID_ENCODING_LENGTH + 1];
227 const char *trans_notes;
228 char dnow[100], dent[100], dpost[100], drecn[100];
229
230 if (!gen_logs)
231 {
232 PINFO ("Attempt to write disabled transaction log");
233 return;
234 }
235 if (!trans_log_stream.is_open()) return;
236
237 gnc_time64_to_iso8601_buff (gnc_time(nullptr), dnow);
238 gnc_time64_to_iso8601_buff (trans->date_entered, dent);
239 gnc_time64_to_iso8601_buff (trans->date_posted, dpost);
240 guid_to_string_buff (xaccTransGetGUID(trans), trans_guid_str);
241 trans_notes = xaccTransGetNotes(trans);
242 trans_log_stream << "===== START\n";
243
244 for (node = trans->splits; node; node = node->next)
245 {
246 Split *split = GNC_SPLIT(node->data);
247 const char * accname = "";
248 char acc_guid_str[GUID_ENCODING_LENGTH + 1];
249 gnc_numeric amt, val;
250
251 if (xaccSplitGetAccount(split))
252 {
253 accname = xaccAccountGetName (xaccSplitGetAccount(split));
255 acc_guid_str);
256 }
257 else
258 {
259 acc_guid_str[0] = '\0';
260 }
261
262 gnc_time64_to_iso8601_buff (split->date_reconciled, drecn);
263
264 guid_to_string_buff (xaccSplitGetGUID(split), split_guid_str);
265 amt = xaccSplitGetAmount (split);
266 val = xaccSplitGetValue (split);
267
268 trans_log_stream << flag << '\t'
269 << trans_guid_str << '\t'
270 << split_guid_str << '\t'
271 << dnow << '\t'
272 << dent << '\t'
273 << dpost << '\t'
274 << acc_guid_str << '\t'
275 << (accname ? accname : "") << '\t'
276 << (trans->num ? trans->num : "") << '\t'
277 << (trans->description ? trans->description : "") << '\t'
278 << (trans_notes ? trans_notes : "") << '\t'
279 << (split->memo ? split->memo : "") << '\t'
280 << (split->action ? split->action : "") << '\t'
281 << split->reconciled << '\t'
282 << gnc_numeric_num(amt) << '/' << gnc_numeric_denom(amt) << '\t'
283 << gnc_numeric_num(val) << '/' << gnc_numeric_denom(val) << '\t'
284 << drecn << '\n';
285 }
286
287 trans_log_stream << "===== END" << std::endl;
288}
const char * xaccAccountGetName(const Account *acc)
Get the account's name.
Definition Account.cpp:3289
#define xaccAccountGetGUID(X)
Definition Account.h:252
char * gnc_time64_to_iso8601_buff(time64 time, char *buff)
The gnc_time64_to_iso8601_buff() routine takes the input UTC time64 value and prints it as an ISO-860...
time64 gnc_time(time64 *tbuf)
get the current time
Definition gnc-date.cpp:262
#define xaccTransGetGUID(X)
const char * xaccTransGetNotes(const Transaction *trans)
Gets the transaction Notes.
#define GUID_ENCODING_LENGTH
Number of characters needed to encode a guid as a string not including the null terminator.
Definition guid.h:84
gchar * guid_to_string_buff(const GncGUID *guid, gchar *str)
The guid_to_string_buff() routine puts a null-terminated string encoding of the id into the memory po...
Definition guid.cpp:208
#define xaccSplitGetGUID(X)
Definition Split.h:579
gnc_numeric xaccSplitGetValue(const Split *split)
Returns the value of this split in the transaction's commodity.
Account * xaccSplitGetAccount(const Split *split)
Returns the account of this split, which was set through xaccAccountInsertSplit().
gnc_numeric xaccSplitGetAmount(const Split *split)
Returns the amount of the split in the account's commodity.