1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 """
29 @summary:
30 logging into text files.
31 @author: Ruben Reifenberg
32 """
33
34 from rrlog import Log
35 from rrlog.server import LogServer,RotateLogWriter,RotateWriterFactory
36 from rrlog.server.textwriter import TextlineLogWriter
37
38
39 -def createRotatingServer(filePathPattern, rotateCount, rotateLineMin, tsFormat="std1", filters=None, observers=None, logwriterFactory=None, drop=True, format_line=None):
40 """
41 @param filePathPattern: full log filename incl.path and placeholder for an int (rotate number). E.g."./mylog%d.txt"
42 @param tsFormat: timestamp format. See L{rrlog.server.LogServer.__init__}
43 @param rotateCount: int >>1, how many files to use for rotation
44 @param rotateLineMin: rotate when ~ lines are written. None to switch off rotation.
45 @param filters: default = () See L{rrlog.server.LogServer.__init__}
46 @param observers: default = () See L{rrlog.server.LogServer.__init__}
47 @param logwriterFactory: Creates LogWriter instances (one per file). If None, the module variable LOGWRITER_CLASS is used.
48 @param format_line: See L{rrlog.server.textwriter.TextlineLogWriter.__init__}
49 """
50 if logwriterFactory is None: logwriterFactory = lambda *args,**kwargs:LOGWRITER_CLASS(format_line=format_line,*args,**kwargs)
51 elif format_line is not None: import warnings; warnings.warn("format_line is ignored since logwriterFactory is already specified")
52 return LogServer(
53 writer = RotateLogWriter(
54 getNextWriter=RotateWriterFactory(
55 configs=[FileConfig(
56 filepath=filePathPattern%(i),
57 drop=drop,
58 )
59 for i in range(0,rotateCount)
60 ],
61 writerFactory=logwriterFactory,
62 ).nextWriter,
63 rotateLineMin=rotateLineMin,
64 ),
65 filters = filters,
66 observers = observers,
67 tsFormat = tsFormat,
68 )
69
70 -def createLocalLog(
71 filePathPattern,
72 rotateCount,
73 rotateLineMin,
74 filters=None,
75 observers=None,
76 traceOffset=0,
77 tsFormat="std1",
78 stackMax=5,
79 drop=True,
80 catsEnable=None,
81 catsDisable=None,
82 seFilesExclude=None,
83 format_line=None,
84 name=None,
85 extractStack=True,
86 ):
87 """
88 @param catsEnable: see L{rrlog.Log.__init__}
89 @param catsDisable: see L{rrlog.Log.__init__}
90 @param seFilesExclude: see L{rrlog.Log.__init__}
91 @param filters: see L{rrlog.server.LogServer.__init__}
92 @param observers: see L{rrlog.server.LogServer.__init__}
93 @param tsFormat: timestamp format. See L{rrlog.server.LogServer.__init__}
94 @param filePathPattern: full log filename incl.path and placeholder for an int (rotate number). E.g."./mylog%d.txt"
95 @param rotateCount: int >>1, how many files to use for rotation
96 @param rotateLineMin: rotate when ~ lines are written. None to switch off rotation.
97 @param stackMax: see L{rrlog.Log.__init__}, default: 5 (==log 5 stack levels.)
98 @param drop: if True, drop an eventually existing file. When False, append to an existing one (this is possible with rotateCount==1 only).
99 @param format_line: See L{rrlog.server.textwriter.TextlineLogWriter.__init__}
100 @param name: The log can be identified by its optional name attribute (__repr__ method of the log will use it.)
101 @param extractStack: see L{rrlog.Log.__init__}
102 @return: a Log ready to use
103 """
104 try:
105 filePathPattern%77
106 except TypeError:
107 raise ValueError("filePathPattern (%s) needs a placeholder for the rotate number"%(filePathPattern))
108 return Log(
109 server = createRotatingServer(
110 filePathPattern,
111 rotateCount,
112 rotateLineMin,
113 tsFormat=tsFormat,
114 filters=filters,
115 observers=observers,
116 drop=drop,
117 format_line=format_line,
118 ),
119 traceOffset=traceOffset,
120 stackMax=stackMax,
121 catsEnable=catsEnable,
122 catsDisable=catsDisable,
123 seFilesExclude=seFilesExclude,
124 name=name,
125 extractStack=extractStack,
126 )
127
128
129
130
132 """
133 Describes a single log file.
134 I.e.for log rotation, a sequence of this is required.
135 """
136 - def __init__(self,
137 filepath,
138 drop=True,
139 lazy = False,
140 ):
141 """
142 @param drop: False: Append lines to existing log file (This makes no sense when using file rotation.)
143 True: A new Writer clears the existing logfile.
144 @param filepath: full log filename incl.path
145 @param lazy: If True, file is opened with first log entry.If False, file
146 is opened immediately.
147 """
148 self.filepath = filepath
149 self.lazy = lazy
150 if drop:
151 self.fileopenflag="w"
152 else:
153 self.fileopenflag="a"
154 - def __repr__(self): return "%s[%s]"%(self.__class__.__name__,self.filepath)
155
156
157
158
160 """
161 """
162 - def __init__(self, config, format_line=None):
163 """
164 @param config: FileConfig
165 """
166 TextlineLogWriter.__init__(self, format_line=format_line)
167 self._config = config
168 if not config.lazy:
169 self._createFile()
170 else:
171 self._logfile = None
172
173
175 self._logfile = open(self._config.filepath,self._config.fileopenflag)
176
177
178
180 """
181 Write without buffering, return when written.
182 Flushes the file after each write.
183 """
184 if self._logfile is None:
185
186 self._createFile()
187 self._lineCount += 1
188
189 self._logfile.write(self._format_line[0](job))
190 self._logfile.flush()
191
192
193 LOGWRITER_CLASS = FileLogWriter
194