Add the commit ID key as constant for log label (#158)

* add the commit id constant

* add changeset lib

* add doc.go with explanation
This commit is contained in:
Yanwei Guo 2018-11-06 14:59:36 -08:00 committed by Knative Prow Robot
parent af2c4bc84e
commit 088e3f7faf
7 changed files with 195 additions and 2 deletions

64
changeset/commit.go Normal file
View File

@ -0,0 +1,64 @@
/*
Copyright 2018 The Knative Authors
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 changeset
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"regexp"
"strings"
)
const (
commitIDFile = "HEAD"
koDataPathEnvName = "KO_DATA_PATH"
)
var (
commitIDRE = regexp.MustCompile(`^[a-f0-9]{40}$`)
)
// Get tries to fetch the first 7 digitals of GitHub commit ID from HEAD file in
// KO_DATA_PATH. If it fails, it returns the error it gets.
func Get() (string, error) {
data, err := readFileFromKoData(commitIDFile)
if err != nil {
return "", err
}
commitID := strings.TrimSpace(string(data))
if !commitIDRE.MatchString(commitID) {
err := fmt.Errorf("%q is not a valid GitHub commit ID", commitID)
return "", err
}
return string(commitID[0:7]), nil
}
// readFileFromKoData tries to read data as string from the file with given name
// under KO_DATA_PATH then returns the content as string. The file is expected
// to be wrapped into the container from /kodata by ko. If it fails, returns
// the error it gets.
func readFileFromKoData(filename string) ([]byte, error) {
koDataPath := os.Getenv(koDataPathEnvName)
if koDataPath == "" {
err := fmt.Errorf("%q does not exist or is empty", koDataPathEnvName)
return nil, err
}
fullFilename := filepath.Join(koDataPath, filename)
return ioutil.ReadFile(fullFilename)
}

88
changeset/commit_test.go Normal file
View File

@ -0,0 +1,88 @@
/*
Copyright 2018 The Knative Authors
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 changeset
import (
"fmt"
"os"
"testing"
)
const (
nonCommittedHeadContext = "ref: refs/heads/non_committed_branch"
testCommitID = "a2d1bdf"
)
func TestReadFile(t *testing.T) {
tests := []struct {
name string
koDataPath string
koDataPathEnvDoesNotExist bool
want string
wantErr bool
err error
}{{
name: "committed branch",
koDataPath: "testdata",
want: testCommitID,
}, {
name: "non committed branch",
koDataPath: "testdata/noncommitted",
wantErr: true,
err: fmt.Errorf("%q is not a valid GitHub commit ID", nonCommittedHeadContext),
}, {
name: "KO_DATA_PATH is empty",
koDataPath: "",
wantErr: true,
err: fmt.Errorf("%q does not exist or is empty", koDataPathEnvName),
}, {
name: "KO_DATA_PATH does not exist",
koDataPath: "",
wantErr: true,
koDataPathEnvDoesNotExist: true,
err: fmt.Errorf("%q does not exist or is empty", koDataPathEnvName),
}, {
name: "HEAD file does not exist",
koDataPath: "testdata/nonexisting",
wantErr: true,
err: fmt.Errorf("open testdata/nonexisting/HEAD: no such file or directory"),
}}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
if test.koDataPathEnvDoesNotExist {
os.Clearenv()
} else {
os.Setenv(koDataPathEnvName, test.koDataPath)
}
got, err := Get()
if (err != nil) != test.wantErr {
t.Errorf("Get() = %v", err)
}
if !test.wantErr {
if test.want != got {
t.Errorf("wanted %q but got %q", test.want, got)
}
} else {
if err == nil || err.Error() != test.err.Error() {
t.Errorf("wanted error %v but got: %v", test.err, err)
}
}
})
}
}

23
changeset/doc.go Normal file
View File

@ -0,0 +1,23 @@
/*
Copyright 2018 The Knative Authors
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 changeset provides Knative utilities for fetching GitHub Commit ID
// from kodata directory. It requires GitHub HEAD file to be linked into
// Knative component source code via the following command:
// ln -s -r .git/HEAD ./cmd/<knative-component-name>/kodata/
// Then ko will build this file into $KO_DATA_PATH when building the container
// for a Knative component.
package changeset

1
changeset/testdata/HEAD vendored Normal file
View File

@ -0,0 +1 @@
a2d1bdfe929516d7da141aef68631a7ee6941b2d

1
changeset/testdata/noncommitted/HEAD vendored Normal file
View File

@ -0,0 +1 @@
ref: refs/heads/non_committed_branch

View File

@ -25,6 +25,7 @@ import (
"go.uber.org/zap/zapcore"
corev1 "k8s.io/api/core/v1"
"github.com/knative/pkg/changeset"
"github.com/knative/pkg/logging/logkey"
)
@ -37,7 +38,7 @@ import (
func NewLogger(configJSON string, levelOverride string, opts ...zap.Option) (*zap.SugaredLogger, zap.AtomicLevel) {
logger, atomicLevel, err := newLoggerFromConfig(configJSON, levelOverride, opts)
if err == nil {
return logger.Sugar(), atomicLevel
return enrichLoggerWithCommitID(logger.Sugar()), atomicLevel
}
loggingCfg := zap.NewProductionConfig()
@ -51,7 +52,18 @@ func NewLogger(configJSON string, levelOverride string, opts ...zap.Option) (*za
if err2 != nil {
panic(err2)
}
return logger.Named("fallback-logger").Sugar(), loggingCfg.Level
return enrichLoggerWithCommitID(logger.Named("fallback-logger").Sugar()), loggingCfg.Level
}
func enrichLoggerWithCommitID(logger *zap.SugaredLogger) *zap.SugaredLogger {
commmitID, err := changeset.Get()
if err == nil {
// Enrich logs with GitHub commit ID.
return logger.With(zap.String(logkey.GitHubCommitID, commmitID))
}
logger.Warnf("Fetch GitHub commit ID from kodata failed: %v", err)
return logger
}
// NewLoggerFromConfig creates a logger using the provided Config

View File

@ -55,4 +55,8 @@ const (
// KubernetesService is the key used to represent a Kubernetes service name in logs
KubernetesService = "knative.dev/k8sservice"
// GitHubCommitID is the key used to represent the GitHub Commit ID where the
// Knative component was built from in logs
GitHubCommitID = "commit"
)