Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
B
beego
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
go
beego
Commits
63da3294
Commit
63da3294
authored
Sep 09, 2013
by
astaxie
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
go on modify api
parent
acadea6a
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
17 additions
and
522 deletions
+17
-522
app.go
app.go
+3
-3
cache.go
cache.go
+0
-133
context.go
context.go
+0
-129
controller.go
controller.go
+1
-1
log.go
log.go
+13
-256
No files found.
app.go
View file @
63da3294
...
...
@@ -39,7 +39,7 @@ func (app *App) Run() {
l
,
err
=
net
.
Listen
(
"tcp"
,
addr
)
}
if
err
!=
nil
{
BeeLogger
.
Fat
al
(
"Listen: "
,
err
)
BeeLogger
.
Critic
al
(
"Listen: "
,
err
)
}
err
=
fcgi
.
Serve
(
l
,
app
.
Handlers
)
}
else
{
...
...
@@ -51,7 +51,7 @@ func (app *App) Run() {
}
laddr
,
err
:=
net
.
ResolveTCPAddr
(
"tcp"
,
addr
)
if
nil
!=
err
{
BeeLogger
.
Fat
al
(
"ResolveTCPAddr:"
,
err
)
BeeLogger
.
Critic
al
(
"ResolveTCPAddr:"
,
err
)
}
l
,
err
=
GetInitListner
(
laddr
)
theStoppable
=
newStoppable
(
l
)
...
...
@@ -73,7 +73,7 @@ func (app *App) Run() {
}
}
if
err
!=
nil
{
BeeLogger
.
Fat
al
(
"ListenAndServe: "
,
err
)
BeeLogger
.
Critic
al
(
"ListenAndServe: "
,
err
)
}
}
...
...
cache.go
deleted
100644 → 0
View file @
acadea6a
package
beego
import
(
"errors"
"fmt"
"strconv"
"sync"
"time"
)
var
(
DefaultEvery
int
=
60
// 1 minute
)
type
BeeItem
struct
{
val
interface
{}
Lastaccess
time
.
Time
expired
int
}
func
(
itm
*
BeeItem
)
Access
()
interface
{}
{
itm
.
Lastaccess
=
time
.
Now
()
return
itm
.
val
}
type
BeeCache
struct
{
lock
sync
.
RWMutex
dur
time
.
Duration
items
map
[
string
]
*
BeeItem
Every
int
// Run an expiration check Every seconds
}
// NewDefaultCache returns a new FileCache with sane defaults.
func
NewBeeCache
()
*
BeeCache
{
cache
:=
BeeCache
{
dur
:
time
.
Since
(
time
.
Now
()),
Every
:
DefaultEvery
}
return
&
cache
}
func
(
bc
*
BeeCache
)
Get
(
name
string
)
interface
{}
{
bc
.
lock
.
RLock
()
defer
bc
.
lock
.
RUnlock
()
itm
,
ok
:=
bc
.
items
[
name
]
if
!
ok
{
return
nil
}
return
itm
.
Access
()
}
func
(
bc
*
BeeCache
)
Put
(
name
string
,
value
interface
{},
expired
int
)
error
{
bc
.
lock
.
Lock
()
defer
bc
.
lock
.
Unlock
()
t
:=
BeeItem
{
val
:
value
,
Lastaccess
:
time
.
Now
(),
expired
:
expired
}
if
_
,
ok
:=
bc
.
items
[
name
];
ok
{
return
errors
.
New
(
"the key is exist"
)
}
else
{
bc
.
items
[
name
]
=
&
t
}
return
nil
}
func
(
bc
*
BeeCache
)
Delete
(
name
string
)
(
ok
bool
,
err
error
)
{
bc
.
lock
.
Lock
()
defer
bc
.
lock
.
Unlock
()
if
_
,
ok
=
bc
.
items
[
name
];
!
ok
{
return
}
delete
(
bc
.
items
,
name
)
_
,
valid
:=
bc
.
items
[
name
]
if
valid
{
ok
=
false
}
return
}
// Return all of the item in a BeeCache
func
(
bc
*
BeeCache
)
Items
()
map
[
string
]
*
BeeItem
{
return
bc
.
items
}
func
(
bc
*
BeeCache
)
IsExist
(
name
string
)
bool
{
bc
.
lock
.
RLock
()
defer
bc
.
lock
.
RUnlock
()
_
,
ok
:=
bc
.
items
[
name
]
return
ok
}
// Start activates the file cache; it will
func
(
bc
*
BeeCache
)
Start
()
error
{
dur
,
err
:=
time
.
ParseDuration
(
fmt
.
Sprintf
(
"%ds"
,
bc
.
Every
))
if
err
!=
nil
{
return
err
}
bc
.
dur
=
dur
bc
.
items
=
make
(
map
[
string
]
*
BeeItem
,
0
)
go
bc
.
vaccuum
()
return
nil
}
func
(
bc
*
BeeCache
)
vaccuum
()
{
if
bc
.
Every
<
1
{
return
}
for
{
<-
time
.
After
(
time
.
Duration
(
bc
.
dur
))
if
bc
.
items
==
nil
{
return
}
for
name
,
_
:=
range
bc
.
items
{
bc
.
item_expired
(
name
)
}
}
}
// item_expired returns true if an item is expired.
func
(
bc
*
BeeCache
)
item_expired
(
name
string
)
bool
{
bc
.
lock
.
Lock
()
defer
bc
.
lock
.
Unlock
()
itm
,
ok
:=
bc
.
items
[
name
]
if
!
ok
{
return
true
}
dur
:=
time
.
Now
()
.
Sub
(
itm
.
Lastaccess
)
sec
,
err
:=
strconv
.
Atoi
(
fmt
.
Sprintf
(
"%0.0f"
,
dur
.
Seconds
()))
if
err
!=
nil
{
delete
(
bc
.
items
,
name
)
return
true
}
else
if
sec
>=
itm
.
expired
{
delete
(
bc
.
items
,
name
)
return
true
}
return
false
}
context.go
deleted
100644 → 0
View file @
acadea6a
package
beego
import
(
"bytes"
"fmt"
"mime"
"net/http"
"strings"
)
type
Context
struct
{
ResponseWriter
http
.
ResponseWriter
Request
*
http
.
Request
RequestBody
[]
byte
Params
map
[
string
]
string
}
func
(
ctx
*
Context
)
WriteString
(
content
string
)
{
ctx
.
ResponseWriter
.
Write
([]
byte
(
content
))
}
func
(
ctx
*
Context
)
Abort
(
status
int
,
body
string
)
{
ctx
.
ResponseWriter
.
WriteHeader
(
status
)
ctx
.
ResponseWriter
.
Write
([]
byte
(
body
))
}
func
(
ctx
*
Context
)
Redirect
(
status
int
,
url_
string
)
{
ctx
.
ResponseWriter
.
Header
()
.
Set
(
"Location"
,
url_
)
ctx
.
ResponseWriter
.
WriteHeader
(
status
)
}
func
(
ctx
*
Context
)
NotModified
()
{
ctx
.
ResponseWriter
.
WriteHeader
(
304
)
}
func
(
ctx
*
Context
)
NotFound
(
message
string
)
{
ctx
.
ResponseWriter
.
WriteHeader
(
404
)
ctx
.
ResponseWriter
.
Write
([]
byte
(
message
))
}
//Sets the content type by extension, as defined in the mime package.
//For example, ctx.ContentType("json") sets the content-type to "application/json"
func
(
ctx
*
Context
)
ContentType
(
ext
string
)
{
if
!
strings
.
HasPrefix
(
ext
,
"."
)
{
ext
=
"."
+
ext
}
ctype
:=
mime
.
TypeByExtension
(
ext
)
if
ctype
!=
""
{
ctx
.
ResponseWriter
.
Header
()
.
Set
(
"Content-Type"
,
ctype
)
}
}
func
(
ctx
*
Context
)
SetHeader
(
hdr
string
,
val
string
,
unique
bool
)
{
if
unique
{
ctx
.
ResponseWriter
.
Header
()
.
Set
(
hdr
,
val
)
}
else
{
ctx
.
ResponseWriter
.
Header
()
.
Add
(
hdr
,
val
)
}
}
//Sets a cookie -- duration is the amount of time in seconds. 0 = forever
//params:
//string name
//string value
//int64 expire = 0
//string $path
//string $domain
//bool $secure = false
//bool $httponly = false
func
(
ctx
*
Context
)
SetCookie
(
name
string
,
value
string
,
others
...
interface
{})
{
var
b
bytes
.
Buffer
fmt
.
Fprintf
(
&
b
,
"%s=%s"
,
sanitizeName
(
name
),
sanitizeValue
(
value
))
if
len
(
others
)
>
0
{
switch
others
[
0
]
.
(
type
)
{
case
int
:
if
others
[
0
]
.
(
int
)
>
0
{
fmt
.
Fprintf
(
&
b
,
"; Max-Age=%d"
,
others
[
0
]
.
(
int
))
}
else
if
others
[
0
]
.
(
int
)
<
0
{
fmt
.
Fprintf
(
&
b
,
"; Max-Age=0"
)
}
case
int64
:
if
others
[
0
]
.
(
int64
)
>
0
{
fmt
.
Fprintf
(
&
b
,
"; Max-Age=%d"
,
others
[
0
]
.
(
int64
))
}
else
if
others
[
0
]
.
(
int64
)
<
0
{
fmt
.
Fprintf
(
&
b
,
"; Max-Age=0"
)
}
case
int32
:
if
others
[
0
]
.
(
int32
)
>
0
{
fmt
.
Fprintf
(
&
b
,
"; Max-Age=%d"
,
others
[
0
]
.
(
int32
))
}
else
if
others
[
0
]
.
(
int32
)
<
0
{
fmt
.
Fprintf
(
&
b
,
"; Max-Age=0"
)
}
}
}
if
len
(
others
)
>
1
{
fmt
.
Fprintf
(
&
b
,
"; Path=%s"
,
sanitizeValue
(
others
[
1
]
.
(
string
)))
}
if
len
(
others
)
>
2
{
fmt
.
Fprintf
(
&
b
,
"; Domain=%s"
,
sanitizeValue
(
others
[
2
]
.
(
string
)))
}
if
len
(
others
)
>
3
{
fmt
.
Fprintf
(
&
b
,
"; Secure"
)
}
if
len
(
others
)
>
4
{
fmt
.
Fprintf
(
&
b
,
"; HttpOnly"
)
}
ctx
.
SetHeader
(
"Set-Cookie"
,
b
.
String
(),
false
)
}
var
cookieNameSanitizer
=
strings
.
NewReplacer
(
"
\n
"
,
"-"
,
"
\r
"
,
"-"
)
func
sanitizeName
(
n
string
)
string
{
return
cookieNameSanitizer
.
Replace
(
n
)
}
var
cookieValueSanitizer
=
strings
.
NewReplacer
(
"
\n
"
,
" "
,
"
\r
"
,
" "
,
";"
,
" "
)
func
sanitizeValue
(
v
string
)
string
{
return
cookieValueSanitizer
.
Replace
(
v
)
}
func
(
ctx
*
Context
)
GetCookie
(
key
string
)
string
{
keycookie
,
err
:=
ctx
.
Request
.
Cookie
(
key
)
if
err
!=
nil
{
return
""
}
return
keycookie
.
Value
}
controller.go
View file @
63da3294
...
...
@@ -36,7 +36,7 @@ type Controller struct {
}
type
ControllerInterface
interface
{
Init
(
ct
*
Context
,
childName
string
)
Init
(
ct
*
context
.
Context
,
childName
string
)
Prepare
()
Get
()
Post
()
...
...
log.go
View file @
63da3294
package
beego
import
(
"fmt"
"io/ioutil"
"log"
"os"
"path"
"path/filepath"
"strings"
"sync"
"time"
"github.com/astaxie/beego/logs"
)
type
FileLogWriter
struct
{
*
log
.
Logger
mw
*
MuxWriter
// The opened file
filename
string
maxlines
int
maxlines_curlines
int
// Rotate at size
maxsize
int
maxsize_cursize
int
// Rotate daily
daily
bool
maxdays
int64
daily_opendate
int
rotate
bool
startLock
sync
.
Mutex
// Only one log can write to the file
}
type
MuxWriter
struct
{
sync
.
Mutex
fd
*
os
.
File
}
func
(
l
*
MuxWriter
)
Write
(
b
[]
byte
)
(
int
,
error
)
{
l
.
Lock
()
defer
l
.
Unlock
()
return
l
.
fd
.
Write
(
b
)
}
func
(
l
*
MuxWriter
)
SetFd
(
fd
*
os
.
File
)
{
if
l
.
fd
!=
nil
{
l
.
fd
.
Close
()
}
l
.
fd
=
fd
}
func
NewFileWriter
(
fname
string
,
rotate
bool
)
*
FileLogWriter
{
w
:=
&
FileLogWriter
{
filename
:
fname
,
maxlines
:
1000000
,
maxsize
:
1
<<
28
,
//256 MB
daily
:
true
,
maxdays
:
7
,
rotate
:
rotate
,
}
// use MuxWriter instead direct use os.File for lock write when rotate
w
.
mw
=
new
(
MuxWriter
)
// set MuxWriter as Logger's io.Writer
w
.
Logger
=
log
.
New
(
w
.
mw
,
""
,
log
.
Ldate
|
log
.
Ltime
)
return
w
}
// Set rotate at linecount (chainable). Must be called before call StartLogger
func
(
w
*
FileLogWriter
)
SetRotateLines
(
maxlines
int
)
*
FileLogWriter
{
w
.
maxlines
=
maxlines
return
w
}
// Set rotate at size (chainable). Must be called before call StartLogger
func
(
w
*
FileLogWriter
)
SetRotateSize
(
maxsize
int
)
*
FileLogWriter
{
w
.
maxsize
=
maxsize
return
w
}
// Set rotate daily (chainable). Must be called before call StartLogger
func
(
w
*
FileLogWriter
)
SetRotateDaily
(
daily
bool
)
*
FileLogWriter
{
w
.
daily
=
daily
return
w
}
// Set rotate daily's log keep for maxdays, other will delete
func
(
w
*
FileLogWriter
)
SetRotateMaxDays
(
maxdays
int64
)
*
FileLogWriter
{
w
.
maxdays
=
maxdays
return
w
}
func
(
w
*
FileLogWriter
)
StartLogger
()
error
{
fd
,
err
:=
w
.
createLogFile
()
if
err
!=
nil
{
return
err
}
w
.
mw
.
SetFd
(
fd
)
err
=
w
.
initFd
()
if
err
!=
nil
{
return
err
}
BeeLogger
=
w
return
nil
}
func
(
w
*
FileLogWriter
)
docheck
(
size
int
)
{
w
.
startLock
.
Lock
()
defer
w
.
startLock
.
Unlock
()
if
(
w
.
maxlines
>
0
&&
w
.
maxlines_curlines
>=
w
.
maxlines
)
||
(
w
.
maxsize
>
0
&&
w
.
maxsize_cursize
>=
w
.
maxsize
)
||
(
w
.
daily
&&
time
.
Now
()
.
Day
()
!=
w
.
daily_opendate
)
{
if
err
:=
w
.
DoRotate
();
err
!=
nil
{
fmt
.
Fprintf
(
os
.
Stderr
,
"FileLogWriter(%q): %s
\n
"
,
w
.
filename
,
err
)
return
}
}
w
.
maxlines_curlines
++
w
.
maxsize_cursize
+=
size
}
func
(
w
*
FileLogWriter
)
Printf
(
format
string
,
v
...
interface
{})
{
// Perform the write
str
:=
fmt
.
Sprintf
(
format
,
v
...
)
n
:=
24
+
len
(
str
)
// 24 stand for the length "2013/06/23 21:00:22 [T] "
w
.
docheck
(
n
)
w
.
Logger
.
Printf
(
format
,
v
...
)
}
func
(
w
*
FileLogWriter
)
createLogFile
()
(
*
os
.
File
,
error
)
{
// Open the log file
fd
,
err
:=
os
.
OpenFile
(
w
.
filename
,
os
.
O_WRONLY
|
os
.
O_APPEND
|
os
.
O_CREATE
,
0660
)
return
fd
,
err
}
func
(
w
*
FileLogWriter
)
initFd
()
error
{
fd
:=
w
.
mw
.
fd
finfo
,
err
:=
fd
.
Stat
()
if
err
!=
nil
{
return
fmt
.
Errorf
(
"get stat err: %s
\n
"
,
err
)
}
w
.
maxsize_cursize
=
int
(
finfo
.
Size
())
w
.
daily_opendate
=
time
.
Now
()
.
Day
()
if
finfo
.
Size
()
>
0
{
content
,
err
:=
ioutil
.
ReadFile
(
w
.
filename
)
if
err
!=
nil
{
fmt
.
Println
(
err
)
}
w
.
maxlines_curlines
=
len
(
strings
.
Split
(
string
(
content
),
"
\n
"
))
}
else
{
w
.
maxlines_curlines
=
0
}
return
nil
}
func
(
w
*
FileLogWriter
)
DoRotate
()
error
{
_
,
err
:=
os
.
Lstat
(
w
.
filename
)
if
err
==
nil
{
// file exists
// Find the next available number
num
:=
1
fname
:=
""
for
;
err
==
nil
&&
num
<=
999
;
num
++
{
fname
=
w
.
filename
+
fmt
.
Sprintf
(
".%s.%03d"
,
time
.
Now
()
.
Format
(
"2006-01-02"
),
num
)
_
,
err
=
os
.
Lstat
(
fname
)
}
// return error if the last file checked still existed
if
err
==
nil
{
return
fmt
.
Errorf
(
"Rotate: Cannot find free log number to rename %s
\n
"
,
w
.
filename
)
}
// block Logger's io.Writer
w
.
mw
.
Lock
()
defer
w
.
mw
.
Unlock
()
fd
:=
w
.
mw
.
fd
fd
.
Close
()
// close fd before rename
// Rename the file to its newfound home
err
=
os
.
Rename
(
w
.
filename
,
fname
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"Rotate: %s
\n
"
,
err
)
}
// re-start logger
err
=
w
.
StartLogger
()
if
err
!=
nil
{
return
fmt
.
Errorf
(
"Rotate StartLogger: %s
\n
"
,
err
)
}
go
w
.
deleteOldLog
()
}
return
nil
}
func
(
w
*
FileLogWriter
)
deleteOldLog
()
{
dir
:=
path
.
Dir
(
w
.
filename
)
filepath
.
Walk
(
dir
,
func
(
path
string
,
info
os
.
FileInfo
,
err
error
)
error
{
if
!
info
.
IsDir
()
&&
info
.
ModTime
()
.
Unix
()
<
(
time
.
Now
()
.
Unix
()
-
60
*
60
*
24
*
w
.
maxdays
)
{
if
strings
.
HasPrefix
(
filepath
.
Base
(
path
),
filepath
.
Base
(
w
.
filename
))
{
os
.
Remove
(
path
)
}
}
return
nil
})
}
// Log levels to control the logging output.
const
(
LevelTrace
=
iota
...
...
@@ -220,88 +14,51 @@ const (
LevelCritical
)
// logLevel controls the global log level used by the logger.
var
level
=
LevelTrace
// LogLevel returns the global log level and can be used in
// own implementations of the logger interface.
func
Level
()
int
{
return
level
}
// SetLogLevel sets the global log level used by the simple
// logger.
func
SetLevel
(
l
int
)
{
level
=
l
}
type
IBeeLogger
interface
{
Fatal
(
v
...
interface
{})
Fatalf
(
format
string
,
v
...
interface
{})
Fatalln
(
v
...
interface
{})
Flags
()
int
Output
(
calldepth
int
,
s
string
)
error
Panic
(
v
...
interface
{})
Panicf
(
format
string
,
v
...
interface
{})
Panicln
(
v
...
interface
{})
Prefix
()
string
Print
(
v
...
interface
{})
Printf
(
format
string
,
v
...
interface
{})
Println
(
v
...
interface
{})
SetFlags
(
flag
int
)
SetPrefix
(
prefix
string
)
BeeLogger
.
SetLevel
(
l
)
}
// logger references the used application logger.
var
BeeLogger
I
BeeLogger
var
BeeLogger
*
logs
.
BeeLogger
func
init
()
{
BeeLogger
=
log
.
New
(
os
.
Stdout
,
""
,
log
.
Ldate
|
log
.
Ltime
)
BeeLogger
=
logs
.
NewLogger
(
10000
)
BeeLogger
.
SetLogger
(
"console"
,
""
)
}
// SetLogger sets a new logger.
func
SetLogger
(
l
*
log
.
Logger
)
{
BeeLogger
=
l
func
SetLogger
(
adaptername
string
,
config
string
)
{
BeeLogger
.
SetLogger
(
adaptername
,
config
)
}
// Trace logs a message at trace level.
func
Trace
(
v
...
interface
{})
{
if
level
<=
LevelTrace
{
BeeLogger
.
Printf
(
"[T] %v
\n
"
,
v
)
}
BeeLogger
.
Trace
(
"%v"
,
v
...
)
}
// Debug logs a message at debug level.
func
Debug
(
v
...
interface
{})
{
if
level
<=
LevelDebug
{
BeeLogger
.
Printf
(
"[D] %v
\n
"
,
v
)
}
BeeLogger
.
Debug
(
"%v"
,
v
...
)
}
// Info logs a message at info level.
func
Info
(
v
...
interface
{})
{
if
level
<=
LevelInfo
{
BeeLogger
.
Printf
(
"[I] %v
\n
"
,
v
)
}
BeeLogger
.
Info
(
"%v"
,
v
...
)
}
// Warning logs a message at warning level.
func
Warn
(
v
...
interface
{})
{
if
level
<=
LevelWarning
{
BeeLogger
.
Printf
(
"[W] %v
\n
"
,
v
)
}
BeeLogger
.
Warn
(
"%v"
,
v
...
)
}
// Error logs a message at error level.
func
Error
(
v
...
interface
{})
{
if
level
<=
LevelError
{
BeeLogger
.
Printf
(
"[E] %v
\n
"
,
v
)
}
BeeLogger
.
Error
(
"%v"
,
v
...
)
}
// Critical logs a message at critical level.
func
Critical
(
v
...
interface
{})
{
if
level
<=
LevelCritical
{
BeeLogger
.
Printf
(
"[C] %v
\n
"
,
v
)
}
BeeLogger
.
Critical
(
"%v"
,
v
...
)
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment