-
Notifications
You must be signed in to change notification settings - Fork 312
Add debug endpoints on export #609
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -48,6 +48,12 @@ type Config struct { | |
TruncateWindow time.Duration `env:"TRUNCATE_WINDOW, default=1h"` | ||
MinWindowAge time.Duration `env:"MIN_WINDOW_AGE, default=2h"` | ||
TTL time.Duration `env:"CLEANUP_TTL, default=336h"` | ||
|
||
// Debugging flags follow. These should not be enabled in production | ||
// environments. | ||
|
||
// DebugEndpointEnabled controls whether the debug endpoint is enabled. | ||
DebugEndpoint bool `env:"DEBUG_ENDPOINT"` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. so - I think we want the debug endpoint on the exposure service not the export service. in our current config, the export service is not accessible without IAM There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We may want to verify that both publish and export are using same truncate window. But if getting a /debug on publish/exposure service is lower hanging fruit that's totally fine. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My plan was to do this on all services, just starting with one for now There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looking more... |
||
} | ||
|
||
func (c *Config) BlobstoreConfig() *storage.Config { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
// Copyright 2020 Google LLC | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package export | ||
|
||
import ( | ||
"context" | ||
"encoding/json" | ||
"fmt" | ||
"net/http" | ||
"time" | ||
|
||
exportdatabase "github.com/google/exposure-notifications-server/internal/export/database" | ||
exportmodel "github.com/google/exposure-notifications-server/internal/export/model" | ||
"github.com/google/exposure-notifications-server/internal/logging" | ||
) | ||
|
||
func (s *Server) handleDebug(ctx context.Context) http.HandlerFunc { | ||
logger := logging.FromContext(ctx) | ||
|
||
type response struct { | ||
Config *Config | ||
ExportConfigs []*exportmodel.ExportConfig | ||
ExportBatchEnds map[int64]time.Time | ||
ExportBatchFiles []string | ||
|
||
SignatureInfos []*exportmodel.SignatureInfo | ||
} | ||
|
||
return func(w http.ResponseWriter, r *http.Request) { | ||
ctx := r.Context() | ||
db := s.env.Database() | ||
|
||
exportConfigs, err := exportdatabase.New(db).GetAllExportConfigs(ctx) | ||
if err != nil { | ||
logger.Errorf("failed to get all export configs: %v", err) | ||
w.WriteHeader(http.StatusInternalServerError) | ||
fmt.Fprint(w, http.StatusText(http.StatusInternalServerError)) | ||
return | ||
} | ||
|
||
exportBatchEnds := make(map[int64]time.Time, len(exportConfigs)) | ||
for _, ec := range exportConfigs { | ||
end, err := exportdatabase.New(db).LatestExportBatchEnd(ctx, ec) | ||
if err != nil { | ||
logger.Errorf("failed to get latest export batch end for %d: %v", ec.ConfigID, err) | ||
w.WriteHeader(http.StatusInternalServerError) | ||
fmt.Fprint(w, http.StatusText(http.StatusInternalServerError)) | ||
return | ||
} | ||
exportBatchEnds[ec.ConfigID] = end | ||
} | ||
|
||
exportBatchFiles, err := exportdatabase.New(db).LookupExportFiles(ctx, 4*time.Hour) | ||
if err != nil { | ||
logger.Errorf("failed to get export files: %v", err) | ||
w.WriteHeader(http.StatusInternalServerError) | ||
fmt.Fprint(w, http.StatusText(http.StatusInternalServerError)) | ||
return | ||
} | ||
|
||
signatureInfos, err := exportdatabase.New(db).ListAllSigntureInfos(ctx) | ||
if err != nil { | ||
logger.Errorf("failed to get all signature infos: %v", err) | ||
w.WriteHeader(http.StatusInternalServerError) | ||
fmt.Fprint(w, http.StatusText(http.StatusInternalServerError)) | ||
return | ||
} | ||
|
||
resp := &response{ | ||
Config: s.config, | ||
ExportConfigs: exportConfigs, | ||
ExportBatchEnds: exportBatchEnds, | ||
ExportBatchFiles: exportBatchFiles, | ||
SignatureInfos: signatureInfos, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We could also include the last X uploaded TEKs There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Were we planning a similar debug handler on the publish server? We could dump authorized apps and some of the config it has too. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we should only put on e on the exposure/publish server |
||
} | ||
|
||
w.Header().Set("Content-Type", "application/json") | ||
|
||
e := json.NewEncoder(w) | ||
e.SetIndent("", " ") | ||
if err := e.Encode(resp); err != nil { | ||
panic(err) | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is technically a change in where the logger comes from, but materially it won't matter since we haven't configured different loggers by context ever.