blob: 040005aaae41fe4c6062defe2cd5bd847abc2bd0 [file] [log] [blame]
// Copyright 2018 The Goma Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package exec
import (
"context"
"fmt"
"go.opencensus.io/stats"
"go.opencensus.io/stats/view"
"go.opencensus.io/tag"
"go.chromium.org/goma/server/log"
gomapb "go.chromium.org/goma/server/proto/api"
)
var (
apiErrors = stats.Int64(
"go.chromium.org/goma/server/exec.api-error",
"exec request api-error",
stats.UnitDimensionless)
clientRetries = stats.Int64(
"go.chromium.org/goma/server/exec.client-retry",
"exec request per client retry",
stats.UnitDimensionless)
apiErrorKey = tag.MustNewKey("api-error")
clientRetryKey = tag.MustNewKey("client-retry")
// DefaultViews are the default views provided by this package.
// You need to register the view for data to actually be collected.
DefaultViews = []*view.View{
{
Description: "exec request api-error",
TagKeys: []tag.Key{
apiErrorKey,
},
Measure: apiErrors,
Aggregation: view.Count(),
},
{
Description: "exec request client retry",
TagKeys: []tag.Key{
clientRetryKey,
},
Measure: clientRetries,
Aggregation: view.Count(),
},
{
Description: `counts toolchain selection. result is "used", "found", "requested" or "missed"`,
TagKeys: []tag.Key{
selectorKey,
resultKey,
},
Measure: toolchainSelects,
Aggregation: view.Count(),
},
}
)
func apiErrorValue(ctx context.Context, resp *gomapb.ExecResp) string {
logger := log.FromContext(ctx)
if errVal := resp.GetError(); errVal != gomapb.ExecResp_OK {
// marked as BAD_REQUEST for
// - compiler/subprogram not found
// - bad path_type in command config
// - input root detection failed
logger.Errorf("api-error=%s error_message=%s", errVal, resp.ErrorMessage)
return errVal.String()
}
if len(resp.ErrorMessage) > 0 {
logger.Errorf("api-error=internal: error_messge=%s", resp.ErrorMessage)
return "internal"
}
if len(resp.MissingInput) > 0 {
logger.Errorf("api-error=missing-inputs: missing=%d", len(resp.MissingInput))
return "missing-inputs"
}
return "OK"
}
// RecordAPIError records api-error in resp.
func RecordAPIError(ctx context.Context, resp *gomapb.ExecResp) error {
ctx, err := tag.New(ctx, tag.Upsert(apiErrorKey, apiErrorValue(ctx, resp)))
if err != nil {
return err
}
stats.Record(ctx, apiErrors.M(1))
return nil
}
// RecordRequesterInfo records requester info.
// e.g. client retry count.
func RecordRequesterInfo(ctx context.Context, reqInfo *gomapb.RequesterInfo) error {
return stats.RecordWithTags(ctx, []tag.Mutator{tag.Upsert(clientRetryKey, fmt.Sprintf("%d", reqInfo.GetRetry()))}, clientRetries.M(1))
// TODO: record api version / goma revision etc?
}