| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 package logs | 5 package logs |
| 6 | 6 |
| 7 import ( | 7 import ( |
| 8 "net/url" | 8 "net/url" |
| 9 "time" | 9 "time" |
| 10 | 10 |
| 11 "github.com/golang/protobuf/proto" | 11 "github.com/golang/protobuf/proto" |
| 12 ds "github.com/luci/gae/service/datastore" | 12 ds "github.com/luci/gae/service/datastore" |
| 13 "github.com/luci/luci-go/appengine/logdog/coordinator" | 13 "github.com/luci/luci-go/appengine/logdog/coordinator" |
| 14 "github.com/luci/luci-go/appengine/logdog/coordinator/config" | |
| 15 "github.com/luci/luci-go/common/api/logdog_coordinator/logs/v1" | 14 "github.com/luci/luci-go/common/api/logdog_coordinator/logs/v1" |
| 16 "github.com/luci/luci-go/common/grpcutil" | 15 "github.com/luci/luci-go/common/grpcutil" |
| 17 "github.com/luci/luci-go/common/logdog/types" | 16 "github.com/luci/luci-go/common/logdog/types" |
| 18 log "github.com/luci/luci-go/common/logging" | 17 log "github.com/luci/luci-go/common/logging" |
| 19 "github.com/luci/luci-go/common/proto/logdog/logpb" | 18 "github.com/luci/luci-go/common/proto/logdog/logpb" |
| 20 "github.com/luci/luci-go/common/retry" | 19 "github.com/luci/luci-go/common/retry" |
| 21 "github.com/luci/luci-go/server/logdog/storage" | 20 "github.com/luci/luci-go/server/logdog/storage" |
| 22 "github.com/luci/luci-go/server/logdog/storage/archive" | 21 "github.com/luci/luci-go/server/logdog/storage/archive" |
| 23 "golang.org/x/net/context" | 22 "golang.org/x/net/context" |
| 24 "google.golang.org/grpc/codes" | 23 "google.golang.org/grpc/codes" |
| (...skipping 20 matching lines...) Expand all Loading... |
| 45 func (s *Server) Tail(c context.Context, req *logdog.TailRequest) (*logdog.GetRe
sponse, error) { | 44 func (s *Server) Tail(c context.Context, req *logdog.TailRequest) (*logdog.GetRe
sponse, error) { |
| 46 r := logdog.GetRequest{ | 45 r := logdog.GetRequest{ |
| 47 Path: req.Path, | 46 Path: req.Path, |
| 48 State: req.State, | 47 State: req.State, |
| 49 } | 48 } |
| 50 return s.getImpl(c, &r, true) | 49 return s.getImpl(c, &r, true) |
| 51 } | 50 } |
| 52 | 51 |
| 53 // getImpl is common code shared between Get and Tail endpoints. | 52 // getImpl is common code shared between Get and Tail endpoints. |
| 54 func (s *Server) getImpl(c context.Context, req *logdog.GetRequest, tail bool) (
*logdog.GetResponse, error) { | 53 func (s *Server) getImpl(c context.Context, req *logdog.GetRequest, tail bool) (
*logdog.GetResponse, error) { |
| 54 svc := s.GetServices() |
| 55 |
| 55 // Fetch the log stream state for this log stream. | 56 // Fetch the log stream state for this log stream. |
| 56 u, err := url.Parse(req.Path) | 57 u, err := url.Parse(req.Path) |
| 57 if err != nil { | 58 if err != nil { |
| 58 log.Fields{ | 59 log.Fields{ |
| 59 log.ErrorKey: err, | 60 log.ErrorKey: err, |
| 60 "path": req.Path, | 61 "path": req.Path, |
| 61 }.Errorf(c, "Could not parse path URL.") | 62 }.Errorf(c, "Could not parse path URL.") |
| 62 return nil, grpcutil.Errf(codes.InvalidArgument, "invalid path e
ncoding") | 63 return nil, grpcutil.Errf(codes.InvalidArgument, "invalid path e
ncoding") |
| 63 } | 64 } |
| 64 ls, err := coordinator.NewLogStream(u.Path) | 65 ls, err := coordinator.NewLogStream(u.Path) |
| 65 if err != nil { | 66 if err != nil { |
| 66 log.Fields{ | 67 log.Fields{ |
| 67 log.ErrorKey: err, | 68 log.ErrorKey: err, |
| 68 "path": u.Path, | 69 "path": u.Path, |
| 69 }.Errorf(c, "Invalid path supplied.") | 70 }.Errorf(c, "Invalid path supplied.") |
| 70 return nil, grpcutil.Errf(codes.InvalidArgument, "invalid path v
alue") | 71 return nil, grpcutil.Errf(codes.InvalidArgument, "invalid path v
alue") |
| 71 } | 72 } |
| 72 | 73 |
| 73 // If this log entry is Purged and we're not admin, pretend it doesn't e
xist. | 74 // If this log entry is Purged and we're not admin, pretend it doesn't e
xist. |
| 74 err = ds.Get(c).Get(ls) | 75 err = ds.Get(c).Get(ls) |
| 75 switch err { | 76 switch err { |
| 76 case nil: | 77 case nil: |
| 77 if ls.Purged { | 78 if ls.Purged { |
| 78 » » » if authErr := config.IsAdminUser(c); authErr != nil { | 79 » » » if authErr := coordinator.IsAdminUser(c, svc); authErr !
= nil { |
| 79 log.Fields{ | 80 log.Fields{ |
| 80 log.ErrorKey: authErr, | 81 log.ErrorKey: authErr, |
| 81 }.Warningf(c, "Non-superuser requested purged lo
g.") | 82 }.Warningf(c, "Non-superuser requested purged lo
g.") |
| 82 return nil, grpcutil.Errf(codes.NotFound, "path
not found") | 83 return nil, grpcutil.Errf(codes.NotFound, "path
not found") |
| 83 } | 84 } |
| 84 } | 85 } |
| 85 | 86 |
| 86 case ds.ErrNoSuchEntity: | 87 case ds.ErrNoSuchEntity: |
| 87 log.Fields{ | 88 log.Fields{ |
| 88 "path": u.Path, | 89 "path": u.Path, |
| (...skipping 21 matching lines...) Expand all Loading... |
| 110 var err error | 111 var err error |
| 111 resp.Desc, err = ls.DescriptorValue() | 112 resp.Desc, err = ls.DescriptorValue() |
| 112 if err != nil { | 113 if err != nil { |
| 113 log.WithError(err).Errorf(c, "Failed to deserialize desc
riptor protobuf.") | 114 log.WithError(err).Errorf(c, "Failed to deserialize desc
riptor protobuf.") |
| 114 return nil, grpcutil.Internal | 115 return nil, grpcutil.Internal |
| 115 } | 116 } |
| 116 } | 117 } |
| 117 | 118 |
| 118 // Retrieve requested logs from storage, if requested. | 119 // Retrieve requested logs from storage, if requested. |
| 119 if tail || req.LogCount >= 0 { | 120 if tail || req.LogCount >= 0 { |
| 120 » » resp.Logs, err = s.getLogs(c, req, tail, ls) | 121 » » resp.Logs, err = s.getLogs(c, svc, req, tail, ls) |
| 121 if err != nil { | 122 if err != nil { |
| 122 log.Fields{ | 123 log.Fields{ |
| 123 log.ErrorKey: err, | 124 log.ErrorKey: err, |
| 124 "path": path, | 125 "path": path, |
| 125 }.Errorf(c, "Failed to get logs.") | 126 }.Errorf(c, "Failed to get logs.") |
| 126 return nil, grpcutil.Internal | 127 return nil, grpcutil.Internal |
| 127 } | 128 } |
| 128 } | 129 } |
| 129 | 130 |
| 130 log.Fields{ | 131 log.Fields{ |
| 131 "logCount": len(resp.Logs), | 132 "logCount": len(resp.Logs), |
| 132 }.Debugf(c, "Get request completed successfully.") | 133 }.Debugf(c, "Get request completed successfully.") |
| 133 return &resp, nil | 134 return &resp, nil |
| 134 } | 135 } |
| 135 | 136 |
| 136 func (s *Server) getLogs(c context.Context, req *logdog.GetRequest, tail bool, l
s *coordinator.LogStream) ( | 137 func (s *Server) getLogs(c context.Context, svc coordinator.Services, req *logdo
g.GetRequest, tail bool, |
| 138 » ls *coordinator.LogStream) ( |
| 137 []*logpb.LogEntry, error) { | 139 []*logpb.LogEntry, error) { |
| 138 var st storage.Storage | 140 var st storage.Storage |
| 139 if !ls.Archived() { | 141 if !ls.Archived() { |
| 140 log.Debugf(c, "Log is not archived. Fetching from intermediate s
torage.") | 142 log.Debugf(c, "Log is not archived. Fetching from intermediate s
torage.") |
| 141 | 143 |
| 142 // Logs are not archived. Fetch from intermediate storage. | 144 // Logs are not archived. Fetch from intermediate storage. |
| 143 var err error | 145 var err error |
| 144 » » st, err = s.Storage(c) | 146 » » st, err = svc.IntermediateStorage(c) |
| 145 if err != nil { | 147 if err != nil { |
| 146 return nil, err | 148 return nil, err |
| 147 } | 149 } |
| 148 } else { | 150 } else { |
| 149 log.Debugf(c, "Log is archived. Fetching from archive storage.") | 151 log.Debugf(c, "Log is archived. Fetching from archive storage.") |
| 150 var err error | 152 var err error |
| 151 » » gs, err := s.GSClient(c) | 153 » » gs, err := svc.GSClient(c) |
| 152 if err != nil { | 154 if err != nil { |
| 153 log.WithError(err).Errorf(c, "Failed to create Google St
orage client.") | 155 log.WithError(err).Errorf(c, "Failed to create Google St
orage client.") |
| 154 return nil, err | 156 return nil, err |
| 155 } | 157 } |
| 156 defer func() { | 158 defer func() { |
| 157 if err := gs.Close(); err != nil { | 159 if err := gs.Close(); err != nil { |
| 158 log.WithError(err).Warningf(c, "Failed to close
Google Storage client.") | 160 log.WithError(err).Warningf(c, "Failed to close
Google Storage client.") |
| 159 } | 161 } |
| 160 }() | 162 }() |
| 161 | 163 |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 280 log.ErrorKey: err, | 282 log.ErrorKey: err, |
| 281 "delay": delay, | 283 "delay": delay, |
| 282 }.Warningf(c, "Transient error while fetching tail log; retrying
.") | 284 }.Warningf(c, "Transient error while fetching tail log; retrying
.") |
| 283 }) | 285 }) |
| 284 if err != nil { | 286 if err != nil { |
| 285 log.WithError(err).Errorf(c, "Failed to fetch tail log.") | 287 log.WithError(err).Errorf(c, "Failed to fetch tail log.") |
| 286 return nil, err | 288 return nil, err |
| 287 } | 289 } |
| 288 return [][]byte{data}, err | 290 return [][]byte{data}, err |
| 289 } | 291 } |
| OLD | NEW |