63da3294 by astaxie

go on modify api

1 parent acadea6a
...@@ -39,7 +39,7 @@ func (app *App) Run() { ...@@ -39,7 +39,7 @@ func (app *App) Run() {
39 l, err = net.Listen("tcp", addr) 39 l, err = net.Listen("tcp", addr)
40 } 40 }
41 if err != nil { 41 if err != nil {
42 BeeLogger.Fatal("Listen: ", err) 42 BeeLogger.Critical("Listen: ", err)
43 } 43 }
44 err = fcgi.Serve(l, app.Handlers) 44 err = fcgi.Serve(l, app.Handlers)
45 } else { 45 } else {
...@@ -51,7 +51,7 @@ func (app *App) Run() { ...@@ -51,7 +51,7 @@ func (app *App) Run() {
51 } 51 }
52 laddr, err := net.ResolveTCPAddr("tcp", addr) 52 laddr, err := net.ResolveTCPAddr("tcp", addr)
53 if nil != err { 53 if nil != err {
54 BeeLogger.Fatal("ResolveTCPAddr:", err) 54 BeeLogger.Critical("ResolveTCPAddr:", err)
55 } 55 }
56 l, err = GetInitListner(laddr) 56 l, err = GetInitListner(laddr)
57 theStoppable = newStoppable(l) 57 theStoppable = newStoppable(l)
...@@ -73,7 +73,7 @@ func (app *App) Run() { ...@@ -73,7 +73,7 @@ func (app *App) Run() {
73 } 73 }
74 } 74 }
75 if err != nil { 75 if err != nil {
76 BeeLogger.Fatal("ListenAndServe: ", err) 76 BeeLogger.Critical("ListenAndServe: ", err)
77 } 77 }
78 } 78 }
79 79
......
1 package beego
2
3 import (
4 "errors"
5 "fmt"
6 "strconv"
7 "sync"
8 "time"
9 )
10
11 var (
12 DefaultEvery int = 60 // 1 minute
13 )
14
15 type BeeItem struct {
16 val interface{}
17 Lastaccess time.Time
18 expired int
19 }
20
21 func (itm *BeeItem) Access() interface{} {
22 itm.Lastaccess = time.Now()
23 return itm.val
24 }
25
26 type BeeCache struct {
27 lock sync.RWMutex
28 dur time.Duration
29 items map[string]*BeeItem
30 Every int // Run an expiration check Every seconds
31 }
32
33 // NewDefaultCache returns a new FileCache with sane defaults.
34 func NewBeeCache() *BeeCache {
35 cache := BeeCache{dur: time.Since(time.Now()),
36 Every: DefaultEvery}
37 return &cache
38 }
39
40 func (bc *BeeCache) Get(name string) interface{} {
41 bc.lock.RLock()
42 defer bc.lock.RUnlock()
43 itm, ok := bc.items[name]
44 if !ok {
45 return nil
46 }
47 return itm.Access()
48 }
49
50 func (bc *BeeCache) Put(name string, value interface{}, expired int) error {
51 bc.lock.Lock()
52 defer bc.lock.Unlock()
53 t := BeeItem{val: value, Lastaccess: time.Now(), expired: expired}
54 if _, ok := bc.items[name]; ok {
55 return errors.New("the key is exist")
56 } else {
57 bc.items[name] = &t
58 }
59 return nil
60 }
61
62 func (bc *BeeCache) Delete(name string) (ok bool, err error) {
63 bc.lock.Lock()
64 defer bc.lock.Unlock()
65 if _, ok = bc.items[name]; !ok {
66 return
67 }
68 delete(bc.items, name)
69 _, valid := bc.items[name]
70 if valid {
71 ok = false
72 }
73 return
74 }
75
76 // Return all of the item in a BeeCache
77 func (bc *BeeCache) Items() map[string]*BeeItem {
78 return bc.items
79 }
80
81 func (bc *BeeCache) IsExist(name string) bool {
82 bc.lock.RLock()
83 defer bc.lock.RUnlock()
84 _, ok := bc.items[name]
85 return ok
86 }
87
88 // Start activates the file cache; it will
89 func (bc *BeeCache) Start() error {
90 dur, err := time.ParseDuration(fmt.Sprintf("%ds", bc.Every))
91 if err != nil {
92 return err
93 }
94 bc.dur = dur
95 bc.items = make(map[string]*BeeItem, 0)
96 go bc.vaccuum()
97 return nil
98 }
99
100 func (bc *BeeCache) vaccuum() {
101 if bc.Every < 1 {
102 return
103 }
104 for {
105 <-time.After(time.Duration(bc.dur))
106 if bc.items == nil {
107 return
108 }
109 for name, _ := range bc.items {
110 bc.item_expired(name)
111 }
112 }
113 }
114
115 // item_expired returns true if an item is expired.
116 func (bc *BeeCache) item_expired(name string) bool {
117 bc.lock.Lock()
118 defer bc.lock.Unlock()
119 itm, ok := bc.items[name]
120 if !ok {
121 return true
122 }
123 dur := time.Now().Sub(itm.Lastaccess)
124 sec, err := strconv.Atoi(fmt.Sprintf("%0.0f", dur.Seconds()))
125 if err != nil {
126 delete(bc.items, name)
127 return true
128 } else if sec >= itm.expired {
129 delete(bc.items, name)
130 return true
131 }
132 return false
133 }
1 package beego
2
3 import (
4 "bytes"
5 "fmt"
6 "mime"
7 "net/http"
8 "strings"
9 )
10
11 type Context struct {
12 ResponseWriter http.ResponseWriter
13 Request *http.Request
14 RequestBody []byte
15 Params map[string]string
16 }
17
18 func (ctx *Context) WriteString(content string) {
19 ctx.ResponseWriter.Write([]byte(content))
20 }
21
22 func (ctx *Context) Abort(status int, body string) {
23 ctx.ResponseWriter.WriteHeader(status)
24 ctx.ResponseWriter.Write([]byte(body))
25 }
26
27 func (ctx *Context) Redirect(status int, url_ string) {
28 ctx.ResponseWriter.Header().Set("Location", url_)
29 ctx.ResponseWriter.WriteHeader(status)
30 }
31
32 func (ctx *Context) NotModified() {
33 ctx.ResponseWriter.WriteHeader(304)
34 }
35
36 func (ctx *Context) NotFound(message string) {
37 ctx.ResponseWriter.WriteHeader(404)
38 ctx.ResponseWriter.Write([]byte(message))
39 }
40
41 //Sets the content type by extension, as defined in the mime package.
42 //For example, ctx.ContentType("json") sets the content-type to "application/json"
43 func (ctx *Context) ContentType(ext string) {
44 if !strings.HasPrefix(ext, ".") {
45 ext = "." + ext
46 }
47 ctype := mime.TypeByExtension(ext)
48 if ctype != "" {
49 ctx.ResponseWriter.Header().Set("Content-Type", ctype)
50 }
51 }
52
53 func (ctx *Context) SetHeader(hdr string, val string, unique bool) {
54 if unique {
55 ctx.ResponseWriter.Header().Set(hdr, val)
56 } else {
57 ctx.ResponseWriter.Header().Add(hdr, val)
58 }
59 }
60
61 //Sets a cookie -- duration is the amount of time in seconds. 0 = forever
62
63 //params:
64 //string name
65 //string value
66 //int64 expire = 0
67 //string $path
68 //string $domain
69 //bool $secure = false
70 //bool $httponly = false
71 func (ctx *Context) SetCookie(name string, value string, others ...interface{}) {
72 var b bytes.Buffer
73 fmt.Fprintf(&b, "%s=%s", sanitizeName(name), sanitizeValue(value))
74 if len(others) > 0 {
75 switch others[0].(type) {
76 case int:
77 if others[0].(int) > 0 {
78 fmt.Fprintf(&b, "; Max-Age=%d", others[0].(int))
79 } else if others[0].(int) < 0 {
80 fmt.Fprintf(&b, "; Max-Age=0")
81 }
82 case int64:
83 if others[0].(int64) > 0 {
84 fmt.Fprintf(&b, "; Max-Age=%d", others[0].(int64))
85 } else if others[0].(int64) < 0 {
86 fmt.Fprintf(&b, "; Max-Age=0")
87 }
88 case int32:
89 if others[0].(int32) > 0 {
90 fmt.Fprintf(&b, "; Max-Age=%d", others[0].(int32))
91 } else if others[0].(int32) < 0 {
92 fmt.Fprintf(&b, "; Max-Age=0")
93 }
94 }
95 }
96 if len(others) > 1 {
97 fmt.Fprintf(&b, "; Path=%s", sanitizeValue(others[1].(string)))
98 }
99 if len(others) > 2 {
100 fmt.Fprintf(&b, "; Domain=%s", sanitizeValue(others[2].(string)))
101 }
102 if len(others) > 3 {
103 fmt.Fprintf(&b, "; Secure")
104 }
105 if len(others) > 4 {
106 fmt.Fprintf(&b, "; HttpOnly")
107 }
108 ctx.SetHeader("Set-Cookie", b.String(), false)
109 }
110
111 var cookieNameSanitizer = strings.NewReplacer("\n", "-", "\r", "-")
112
113 func sanitizeName(n string) string {
114 return cookieNameSanitizer.Replace(n)
115 }
116
117 var cookieValueSanitizer = strings.NewReplacer("\n", " ", "\r", " ", ";", " ")
118
119 func sanitizeValue(v string) string {
120 return cookieValueSanitizer.Replace(v)
121 }
122
123 func (ctx *Context) GetCookie(key string) string {
124 keycookie, err := ctx.Request.Cookie(key)
125 if err != nil {
126 return ""
127 }
128 return keycookie.Value
129 }
...@@ -36,7 +36,7 @@ type Controller struct { ...@@ -36,7 +36,7 @@ type Controller struct {
36 } 36 }
37 37
38 type ControllerInterface interface { 38 type ControllerInterface interface {
39 Init(ct *Context, childName string) 39 Init(ct *context.Context, childName string)
40 Prepare() 40 Prepare()
41 Get() 41 Get()
42 Post() 42 Post()
......
1 package beego 1 package beego
2 2
3 import ( 3 import (
4 "fmt" 4 "github.com/astaxie/beego/logs"
5 "io/ioutil"
6 "log"
7 "os"
8 "path"
9 "path/filepath"
10 "strings"
11 "sync"
12 "time"
13 ) 5 )
14 6
15 type FileLogWriter struct {
16 *log.Logger
17 mw *MuxWriter
18 // The opened file
19 filename string
20
21 maxlines int
22 maxlines_curlines int
23
24 // Rotate at size
25 maxsize int
26 maxsize_cursize int
27
28 // Rotate daily
29 daily bool
30 maxdays int64
31 daily_opendate int
32
33 rotate bool
34
35 startLock sync.Mutex // Only one log can write to the file
36 }
37
38 type MuxWriter struct {
39 sync.Mutex
40 fd *os.File
41 }
42
43 func (l *MuxWriter) Write(b []byte) (int, error) {
44 l.Lock()
45 defer l.Unlock()
46 return l.fd.Write(b)
47 }
48
49 func (l *MuxWriter) SetFd(fd *os.File) {
50 if l.fd != nil {
51 l.fd.Close()
52 }
53 l.fd = fd
54 }
55
56 func NewFileWriter(fname string, rotate bool) *FileLogWriter {
57 w := &FileLogWriter{
58 filename: fname,
59 maxlines: 1000000,
60 maxsize: 1 << 28, //256 MB
61 daily: true,
62 maxdays: 7,
63 rotate: rotate,
64 }
65 // use MuxWriter instead direct use os.File for lock write when rotate
66 w.mw = new(MuxWriter)
67 // set MuxWriter as Logger's io.Writer
68 w.Logger = log.New(w.mw, "", log.Ldate|log.Ltime)
69 return w
70 }
71
72 // Set rotate at linecount (chainable). Must be called before call StartLogger
73 func (w *FileLogWriter) SetRotateLines(maxlines int) *FileLogWriter {
74 w.maxlines = maxlines
75 return w
76 }
77
78 // Set rotate at size (chainable). Must be called before call StartLogger
79 func (w *FileLogWriter) SetRotateSize(maxsize int) *FileLogWriter {
80 w.maxsize = maxsize
81 return w
82 }
83
84 // Set rotate daily (chainable). Must be called before call StartLogger
85 func (w *FileLogWriter) SetRotateDaily(daily bool) *FileLogWriter {
86 w.daily = daily
87 return w
88 }
89
90 // Set rotate daily's log keep for maxdays, other will delete
91 func (w *FileLogWriter) SetRotateMaxDays(maxdays int64) *FileLogWriter {
92 w.maxdays = maxdays
93 return w
94 }
95
96 func (w *FileLogWriter) StartLogger() error {
97 fd, err := w.createLogFile()
98 if err != nil {
99 return err
100 }
101 w.mw.SetFd(fd)
102 err = w.initFd()
103 if err != nil {
104 return err
105 }
106 BeeLogger = w
107 return nil
108 }
109
110 func (w *FileLogWriter) docheck(size int) {
111 w.startLock.Lock()
112 defer w.startLock.Unlock()
113 if (w.maxlines > 0 && w.maxlines_curlines >= w.maxlines) ||
114 (w.maxsize > 0 && w.maxsize_cursize >= w.maxsize) ||
115 (w.daily && time.Now().Day() != w.daily_opendate) {
116 if err := w.DoRotate(); err != nil {
117 fmt.Fprintf(os.Stderr, "FileLogWriter(%q): %s\n", w.filename, err)
118 return
119 }
120 }
121 w.maxlines_curlines++
122 w.maxsize_cursize += size
123 }
124
125 func (w *FileLogWriter) Printf(format string, v ...interface{}) {
126 // Perform the write
127 str := fmt.Sprintf(format, v...)
128 n := 24 + len(str) // 24 stand for the length "2013/06/23 21:00:22 [T] "
129
130 w.docheck(n)
131 w.Logger.Printf(format, v...)
132 }
133
134 func (w *FileLogWriter) createLogFile() (*os.File, error) {
135 // Open the log file
136 fd, err := os.OpenFile(w.filename, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0660)
137 return fd, err
138 }
139
140 func (w *FileLogWriter) initFd() error {
141 fd := w.mw.fd
142 finfo, err := fd.Stat()
143 if err != nil {
144 return fmt.Errorf("get stat err: %s\n", err)
145 }
146 w.maxsize_cursize = int(finfo.Size())
147 w.daily_opendate = time.Now().Day()
148 if finfo.Size() > 0 {
149 content, err := ioutil.ReadFile(w.filename)
150 if err != nil {
151 fmt.Println(err)
152 }
153 w.maxlines_curlines = len(strings.Split(string(content), "\n"))
154 } else {
155 w.maxlines_curlines = 0
156 }
157 return nil
158 }
159
160 func (w *FileLogWriter) DoRotate() error {
161 _, err := os.Lstat(w.filename)
162 if err == nil { // file exists
163 // Find the next available number
164 num := 1
165 fname := ""
166 for ; err == nil && num <= 999; num++ {
167 fname = w.filename + fmt.Sprintf(".%s.%03d", time.Now().Format("2006-01-02"), num)
168 _, err = os.Lstat(fname)
169 }
170 // return error if the last file checked still existed
171 if err == nil {
172 return fmt.Errorf("Rotate: Cannot find free log number to rename %s\n", w.filename)
173 }
174
175 // block Logger's io.Writer
176 w.mw.Lock()
177 defer w.mw.Unlock()
178
179 fd := w.mw.fd
180 fd.Close()
181
182 // close fd before rename
183 // Rename the file to its newfound home
184 err = os.Rename(w.filename, fname)
185 if err != nil {
186 return fmt.Errorf("Rotate: %s\n", err)
187 }
188
189 // re-start logger
190 err = w.StartLogger()
191 if err != nil {
192 return fmt.Errorf("Rotate StartLogger: %s\n", err)
193 }
194
195 go w.deleteOldLog()
196 }
197
198 return nil
199 }
200
201 func (w *FileLogWriter) deleteOldLog() {
202 dir := path.Dir(w.filename)
203 filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
204 if !info.IsDir() && info.ModTime().Unix() < (time.Now().Unix()-60*60*24*w.maxdays) {
205 if strings.HasPrefix(filepath.Base(path), filepath.Base(w.filename)) {
206 os.Remove(path)
207 }
208 }
209 return nil
210 })
211 }
212
213 // Log levels to control the logging output. 7 // Log levels to control the logging output.
214 const ( 8 const (
215 LevelTrace = iota 9 LevelTrace = iota
...@@ -220,88 +14,51 @@ const ( ...@@ -220,88 +14,51 @@ const (
220 LevelCritical 14 LevelCritical
221 ) 15 )
222 16
223 // logLevel controls the global log level used by the logger.
224 var level = LevelTrace
225
226 // LogLevel returns the global log level and can be used in
227 // own implementations of the logger interface.
228 func Level() int {
229 return level
230 }
231
232 // SetLogLevel sets the global log level used by the simple 17 // SetLogLevel sets the global log level used by the simple
233 // logger. 18 // logger.
234 func SetLevel(l int) { 19 func SetLevel(l int) {
235 level = l 20 BeeLogger.SetLevel(l)
236 }
237
238 type IBeeLogger interface {
239 Fatal(v ...interface{})
240 Fatalf(format string, v ...interface{})
241 Fatalln(v ...interface{})
242 Flags() int
243 Output(calldepth int, s string) error
244 Panic(v ...interface{})
245 Panicf(format string, v ...interface{})
246 Panicln(v ...interface{})
247 Prefix() string
248 Print(v ...interface{})
249 Printf(format string, v ...interface{})
250 Println(v ...interface{})
251 SetFlags(flag int)
252 SetPrefix(prefix string)
253 } 21 }
254 22
255 // logger references the used application logger. 23 // logger references the used application logger.
256 var BeeLogger IBeeLogger 24 var BeeLogger *logs.BeeLogger
257 25
258 func init() { 26 func init() {
259 BeeLogger = log.New(os.Stdout, "", log.Ldate|log.Ltime) 27 BeeLogger = logs.NewLogger(10000)
28 BeeLogger.SetLogger("console", "")
260 } 29 }
261 30
262 // SetLogger sets a new logger. 31 // SetLogger sets a new logger.
263 func SetLogger(l *log.Logger) { 32 func SetLogger(adaptername string, config string) {
264 BeeLogger = l 33 BeeLogger.SetLogger(adaptername, config)
265 } 34 }
266 35
267 // Trace logs a message at trace level. 36 // Trace logs a message at trace level.
268 func Trace(v ...interface{}) { 37 func Trace(v ...interface{}) {
269 if level <= LevelTrace { 38 BeeLogger.Trace("%v", v...)
270 BeeLogger.Printf("[T] %v\n", v)
271 }
272 } 39 }
273 40
274 // Debug logs a message at debug level. 41 // Debug logs a message at debug level.
275 func Debug(v ...interface{}) { 42 func Debug(v ...interface{}) {
276 if level <= LevelDebug { 43 BeeLogger.Debug("%v", v...)
277 BeeLogger.Printf("[D] %v\n", v)
278 }
279 } 44 }
280 45
281 // Info logs a message at info level. 46 // Info logs a message at info level.
282 func Info(v ...interface{}) { 47 func Info(v ...interface{}) {
283 if level <= LevelInfo { 48 BeeLogger.Info("%v", v...)
284 BeeLogger.Printf("[I] %v\n", v)
285 }
286 } 49 }
287 50
288 // Warning logs a message at warning level. 51 // Warning logs a message at warning level.
289 func Warn(v ...interface{}) { 52 func Warn(v ...interface{}) {
290 if level <= LevelWarning { 53 BeeLogger.Warn("%v", v...)
291 BeeLogger.Printf("[W] %v\n", v)
292 }
293 } 54 }
294 55
295 // Error logs a message at error level. 56 // Error logs a message at error level.
296 func Error(v ...interface{}) { 57 func Error(v ...interface{}) {
297 if level <= LevelError { 58 BeeLogger.Error("%v", v...)
298 BeeLogger.Printf("[E] %v\n", v)
299 }
300 } 59 }
301 60
302 // Critical logs a message at critical level. 61 // Critical logs a message at critical level.
303 func Critical(v ...interface{}) { 62 func Critical(v ...interface{}) {
304 if level <= LevelCritical { 63 BeeLogger.Critical("%v", v...)
305 BeeLogger.Printf("[C] %v\n", v)
306 }
307 } 64 }
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!