|
|
@@ -16,14 +16,63 @@ import ( |
|
|
"github.com/juju/utils"
|
|
|
"github.com/juju/version"
|
|
|
"golang.org/x/net/websocket"
|
|
|
+ "gopkg.in/juju/names.v2"
|
|
|
"gopkg.in/natefinch/lumberjack.v2"
|
|
|
|
|
|
"github.com/juju/juju/apiserver/common"
|
|
|
"github.com/juju/juju/apiserver/params"
|
|
|
"github.com/juju/juju/state"
|
|
|
)
|
|
|
|
|
|
-func newLogSinkHandler(h httpContext, logDir string) http.Handler {
|
|
|
+type DbLogger interface {
|
|
|
+ Log(*params.LogRecord) error
|
|
|
+ Close()
|
|
|
+}
|
|
|
+
|
|
|
+type LoggingStrategy interface {
|
|
|
+ Authenticate(*http.Request) error
|
|
|
+ FilePrefix() string
|
|
|
+ MakeLogger(version.Number) DbLogger
|
|
|
+}
|
|
|
+
|
|
|
+type entityLogger struct {
|
|
|
+ *state.EntityDbLogger
|
|
|
+}
|
|
|
+
|
|
|
+func (l *entityLogger) Log(m *params.LogRecord) error {
|
|
|
+ level, _ := loggo.ParseLevel(m.Level)
|
|
|
+ return l.EntityDbLogger.Log(m.Time, m.Module, m.Location, level, m.Message)
|
|
|
+}
|
|
|
+
|
|
|
+type AgentLoggingStrategy struct {
|
|
|
+ ctxt httpContext
|
|
|
+ st *state.State
|
|
|
+ entity names.Tag
|
|
|
+}
|
|
|
+
|
|
|
+func (s *AgentLoggingStrategy) Authenticate(req *http.Request) error {
|
|
|
+ st, entity, err := s.ctxt.stateForRequestAuthenticatedAgent(req)
|
|
|
+ if err != nil {
|
|
|
+ return errors.Trace(err)
|
|
|
+ }
|
|
|
+ s.st = st
|
|
|
+ s.entity = entity.Tag()
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
+func (s *AgentLoggingStrategy) FilePrefix() string {
|
|
|
+ return s.st.ModelUUID() + " " + s.entity.String() + ":"
|
|
|
+}
|
|
|
+
|
|
|
+func (s *AgentLoggingStrategy) MakeLogger(ver version.Number) DbLogger {
|
|
|
+ return &entityLogger{state.NewEntityDbLogger(s.st, s.entity, ver)}
|
|
|
+}
|
|
|
+
|
|
|
+func newAgentLoggingStrategy(ctxt httpContext) LoggingStrategy {
|
|
|
+ return &AgentLoggingStrategy{ctxt: ctxt}
|
|
|
+}
|
|
|
+
|
|
|
+func newLogSinkHandler(h httpContext, logDir string, newStrategy func(httpContext) LoggingStrategy) http.Handler {
|
|
|
|
|
|
logPath := filepath.Join(logDir, "logsink.log")
|
|
|
if err := primeLogFile(logPath); err != nil {
|
|
|
@@ -33,7 +82,8 @@ func newLogSinkHandler(h httpContext, logDir string) http.Handler { |
|
|
}
|
|
|
|
|
|
return &logSinkHandler{
|
|
|
- ctxt: h,
|
|
|
+ ctxt: h,
|
|
|
+ newStrategy: newStrategy,
|
|
|
fileLogger: &lumberjack.Logger{
|
|
|
Filename: logPath,
|
|
|
MaxSize: 300, // MB
|
|
|
@@ -55,22 +105,23 @@ func primeLogFile(path string) error { |
|
|
}
|
|
|
|
|
|
type logSinkHandler struct {
|
|
|
- ctxt httpContext
|
|
|
- fileLogger io.WriteCloser
|
|
|
+ ctxt httpContext
|
|
|
+ newStrategy func(httpContext) LoggingStrategy
|
|
|
+ fileLogger io.WriteCloser
|
|
|
}
|
|
|
|
|
|
// ServeHTTP implements the http.Handler interface.
|
|
|
func (h *logSinkHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|
|
+ strategy := h.newStrategy(h.ctxt)
|
|
|
server := websocket.Server{
|
|
|
Handler: func(socket *websocket.Conn) {
|
|
|
defer socket.Close()
|
|
|
|
|
|
- st, entity, err := h.ctxt.stateForRequestAuthenticatedAgent(req)
|
|
|
+ err := strategy.Authenticate(req)
|
|
|
if err != nil {
|
|
|
h.sendError(socket, req, err)
|
|
|
return
|
|
|
}
|
|
|
- tag := entity.Tag()
|
|
|
|
|
|
// Note that this endpoint is agent-only. Thus the only
|
|
|
// callers will necessarily provide their Juju version.
|
|
|
@@ -86,8 +137,8 @@ func (h *logSinkHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { |
|
|
return
|
|
|
}
|
|
|
|
|
|
- filePrefix := st.ModelUUID() + " " + tag.String() + ":"
|
|
|
- dbLogger := state.NewEntityDbLogger(st, tag, ver)
|
|
|
+ filePrefix := strategy.FilePrefix()
|
|
|
+ dbLogger := strategy.MakeLogger(ver)
|
|
|
defer dbLogger.Close()
|
|
|
|
|
|
// If we get to here, no more errors to report, so we report a nil
|
|
|
@@ -105,8 +156,7 @@ func (h *logSinkHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { |
|
|
if fileErr != nil {
|
|
|
logger.Errorf("logging to logsink.log failed: %v", fileErr)
|
|
|
}
|
|
|
- level, _ := loggo.ParseLevel(m.Level)
|
|
|
- dbErr := dbLogger.Log(m.Time, m.Module, m.Location, level, m.Message)
|
|
|
+ dbErr := dbLogger.Log(&m)
|
|
|
if dbErr != nil {
|
|
|
logger.Errorf("logging to DB failed: %v", err)
|
|
|
}
|
|
|
|
0 comments on commit
eafd1f8