summaryrefslogtreecommitdiff
path: root/rdiff-backup/rdiff_backup/statistics.py
diff options
context:
space:
mode:
Diffstat (limited to 'rdiff-backup/rdiff_backup/statistics.py')
-rw-r--r--rdiff-backup/rdiff_backup/statistics.py65
1 files changed, 64 insertions, 1 deletions
diff --git a/rdiff-backup/rdiff_backup/statistics.py b/rdiff-backup/rdiff_backup/statistics.py
index 5ed6cd3..c381473 100644
--- a/rdiff-backup/rdiff_backup/statistics.py
+++ b/rdiff-backup/rdiff_backup/statistics.py
@@ -20,7 +20,7 @@
"""Generate and process aggregated backup information"""
import re, os, time
-import Globals, robust, Time, rorpiter, increment, log
+import Globals, Time, increment, log, static
class StatsException(Exception): pass
@@ -347,6 +347,69 @@ def print_active_stats():
"""Print statistics of active statobj to stdout and log"""
global _active_statfileobj
assert _active_statfileobj
+ _active_statfileobj.finish()
statmsg = _active_statfileobj.get_stats_logstring("Session statistics")
log.Log.log_to_file(statmsg)
Globals.client_conn.sys.stdout.write(statmsg)
+
+
+class FileStats:
+ """Keep track of less detailed stats on file-by-file basis"""
+ _fileobj, _rp = None, None
+ _line_sep = None
+ def init(cls):
+ """Open file stats object and prepare to write"""
+ assert not (cls._fileobj or cls._rp), (cls._fileobj, cls._rp)
+ rpbase = Globals.rbdir.append("file_statistics")
+ suffix = Globals.compression and 'data.gz' or 'data'
+ cls._rp = increment.get_inc(rpbase, suffix, Time.curtime)
+ assert not cls._rp.lstat()
+ cls._fileobj = cls._rp.open("wb", compress = Globals.compression)
+
+ cls._line_sep = Globals.null_separator and '\0' or '\n'
+ cls.write_docstring()
+ cls.line_buffer = []
+
+ def write_docstring(cls):
+ """Write the first line (a documentation string) into file"""
+ cls._fileobj.write("# Format of each line in file statistics file:")
+ cls._fileobj.write(cls._line_sep)
+ cls._fileobj.write("# Filename Changed SourceSize MirrorSize "
+ "IncrementSize" + cls._line_sep)
+
+ def update(cls, source_rorp, dest_rorp, changed, inc):
+ """Update file stats with given information"""
+ if source_rorp: filename = source_rorp.get_indexpath()
+ else: filename = dest_rorp.get_indexpath()
+
+ size_list = map(cls.get_size, [source_rorp, dest_rorp, inc])
+ line = " ".join([filename, str(changed)] + size_list)
+ cls.line_buffer.append(line)
+ if len(cls.line_buffer) >= 100: cls.write_buffer()
+
+ def get_size(cls, rorp):
+ """Return the size of rorp as string, or "NA" if not a regular file"""
+ if not rorp: return "NA"
+ if rorp.isreg(): return str(rorp.getsize())
+ else: return "0"
+
+ def write_buffer(cls):
+ """Write buffer to file because buffer is full
+
+ The buffer part is necessary because the GzipFile.write()
+ method seems fairly slow.
+
+ """
+ assert cls.line_buffer and cls._fileobj
+ cls.line_buffer.append('') # have join add _line_sep to end also
+ cls._fileobj.write(cls._line_sep.join(cls.line_buffer))
+ cls.line_buffer = []
+
+ def close(cls):
+ """Close file stats file"""
+ assert cls._fileobj, cls._fileobj
+ if cls.line_buffer: cls.write_buffer()
+ assert not cls._fileobj.close()
+ cls._fileobj = cls._rp = None
+
+static.MakeClass(FileStats)