@@ -3,13 +3,9 @@ package log
33import (
44 "fmt"
55 "io"
6- "io/ioutil"
76 "net"
87 "os"
9- "path/filepath"
108 "reflect"
11- "regexp"
12- "strings"
139 "sync"
1410
1511 "github.com/go-stack/stack"
@@ -74,111 +70,6 @@ func FileHandler(path string, fmtr Format) (Handler, error) {
7470 return closingHandler {f , StreamHandler (f , fmtr )}, nil
7571}
7672
77- // countingWriter wraps a WriteCloser object in order to count the written bytes.
78- type countingWriter struct {
79- w io.WriteCloser // the wrapped object
80- count uint // number of bytes written
81- }
82-
83- // Write increments the byte counter by the number of bytes written.
84- // Implements the WriteCloser interface.
85- func (w * countingWriter ) Write (p []byte ) (n int , err error ) {
86- n , err = w .w .Write (p )
87- w .count += uint (n )
88- return n , err
89- }
90-
91- // Close implements the WriteCloser interface.
92- func (w * countingWriter ) Close () error {
93- return w .w .Close ()
94- }
95-
96- // prepFile opens the log file at the given path, and cuts off the invalid part
97- // from the end, because the previous execution could have been finished by interruption.
98- // Assumes that every line ended by '\n' contains a valid log record.
99- func prepFile (path string ) (* countingWriter , error ) {
100- f , err := os .OpenFile (path , os .O_RDWR | os .O_APPEND , 0600 )
101- if err != nil {
102- return nil , err
103- }
104- _ , err = f .Seek (- 1 , io .SeekEnd )
105- if err != nil {
106- return nil , err
107- }
108- buf := make ([]byte , 1 )
109- var cut int64
110- for {
111- if _ , err := f .Read (buf ); err != nil {
112- return nil , err
113- }
114- if buf [0 ] == '\n' {
115- break
116- }
117- if _ , err = f .Seek (- 2 , io .SeekCurrent ); err != nil {
118- return nil , err
119- }
120- cut ++
121- }
122- fi , err := f .Stat ()
123- if err != nil {
124- return nil , err
125- }
126- ns := fi .Size () - cut
127- if err = f .Truncate (ns ); err != nil {
128- return nil , err
129- }
130- return & countingWriter {w : f , count : uint (ns )}, nil
131- }
132-
133- // RotatingFileHandler returns a handler which writes log records to file chunks
134- // at the given path. When a file's size reaches the limit, the handler creates
135- // a new file named after the timestamp of the first log record it will contain.
136- func RotatingFileHandler (path string , limit uint , formatter Format ) (Handler , error ) {
137- if err := os .MkdirAll (path , 0700 ); err != nil {
138- return nil , err
139- }
140- files , err := ioutil .ReadDir (path )
141- if err != nil {
142- return nil , err
143- }
144- re := regexp .MustCompile (`\.log$` )
145- last := len (files ) - 1
146- for last >= 0 && (! files [last ].Mode ().IsRegular () || ! re .MatchString (files [last ].Name ())) {
147- last --
148- }
149- var counter * countingWriter
150- if last >= 0 && files [last ].Size () < int64 (limit ) {
151- // Open the last file, and continue to write into it until it's size reaches the limit.
152- if counter , err = prepFile (filepath .Join (path , files [last ].Name ())); err != nil {
153- return nil , err
154- }
155- }
156- if counter == nil {
157- counter = new (countingWriter )
158- }
159- h := StreamHandler (counter , formatter )
160-
161- return FuncHandler (func (r * Record ) error {
162- if counter .count > limit {
163- counter .Close ()
164- counter .w = nil
165- }
166- if counter .w == nil {
167- f , err := os .OpenFile (
168- filepath .Join (path , fmt .Sprintf ("%s.log" , strings .Replace (r .Time .Format ("060102150405.00" ), "." , "" , 1 ))),
169- os .O_CREATE | os .O_APPEND | os .O_WRONLY ,
170- 0600 ,
171- )
172- if err != nil {
173- return err
174- }
175- counter .w = f
176- counter .count = 0
177- }
178- return h .Log (r )
179- }), nil
180- }
181-
18273// NetHandler opens a socket to the given address and writes records
18374// over the connection.
18475func NetHandler (network , addr string , fmtr Format ) (Handler , error ) {
0 commit comments