Skip to content
This repository has been archived by the owner on Oct 9, 2023. It is now read-only.

Commit

Permalink
Feat: Add pod start and finish time in RFC3339 time format to logging…
Browse files Browse the repository at this point in the history
… link templating variables #minor (#360)

* Add RFC3339 time format log link vars for start and finish time

Signed-off-by: Fabio Graetz <[email protected]>

* Add RFC3339 timestamp to log link generation tests

Signed-off-by: Fabio Graetz <[email protected]>

---------

Signed-off-by: Fabio Graetz <[email protected]>
  • Loading branch information
fg91 authored Jun 13, 2023
1 parent 2a7a6f9 commit 53e63bc
Show file tree
Hide file tree
Showing 4 changed files with 163 additions and 93 deletions.
21 changes: 13 additions & 8 deletions go/tasks/logs/logging_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,21 @@ func GetLogsForContainerInPod(ctx context.Context, logPlugin tasklog.Plugin, pod
return nil, nil
}

startTime := pod.CreationTimestamp.Unix()
finishTime := time.Now().Unix()

logs, err := logPlugin.GetTaskLogs(
tasklog.Input{
PodName: pod.Name,
PodUID: string(pod.GetUID()),
Namespace: pod.Namespace,
ContainerName: pod.Spec.Containers[index].Name,
ContainerID: pod.Status.ContainerStatuses[index].ContainerID,
LogName: nameSuffix,
PodUnixStartTime: pod.CreationTimestamp.Unix(),
PodUnixFinishTime: time.Now().Unix(),
PodName: pod.Name,
PodUID: string(pod.GetUID()),
Namespace: pod.Namespace,
ContainerName: pod.Spec.Containers[index].Name,
ContainerID: pod.Status.ContainerStatuses[index].ContainerID,
LogName: nameSuffix,
PodRFC3339StartTime: time.Unix(startTime, 0).Format(time.RFC3339),
PodRFC3339FinishTime: time.Unix(finishTime, 0).Format(time.RFC3339),
PodUnixStartTime: startTime,
PodUnixFinishTime: finishTime,
},
)

Expand Down
20 changes: 11 additions & 9 deletions go/tasks/pluginmachinery/tasklog/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,17 @@ import "github.com/flyteorg/flyteidl/gen/pb-go/flyteidl/core"
// Input contains all available information about task's execution that a log plugin can use to construct task's
// log links.
type Input struct {
HostName string `json:"hostname"`
PodName string `json:"podName"`
Namespace string `json:"namespace"`
ContainerName string `json:"containerName"`
ContainerID string `json:"containerId"`
LogName string `json:"logName"`
PodUnixStartTime int64 `json:"podUnixStartTime"`
PodUnixFinishTime int64 `json:"podUnixFinishTime"`
PodUID string `json:"podUID"`
HostName string `json:"hostname"`
PodName string `json:"podName"`
Namespace string `json:"namespace"`
ContainerName string `json:"containerName"`
ContainerID string `json:"containerId"`
LogName string `json:"logName"`
PodRFC3339StartTime string `json:"podRFC3339StartTime"`
PodRFC3339FinishTime string `json:"podRFC3339FinishTime"`
PodUnixStartTime int64 `json:"podUnixStartTime"`
PodUnixFinishTime int64 `json:"podUnixFinishTime"`
PodUID string `json:"podUID"`
}

// Output contains all task logs a plugin generates for a given Input.
Expand Down
72 changes: 45 additions & 27 deletions go/tasks/pluginmachinery/tasklog/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import (
// {{ .containerId }}: The container id docker/crio generated at run time,
// {{ .logName }}: A deployment specific name where to expect the logs to be.
// {{ .hostname }}: The hostname where the pod is running and where logs reside.
// {{ .PodRFC3339StartTime }}: The pod creation time in RFC3339 format
// {{ .PodRFC3339FinishTime }}: Don't have a good mechanism for this yet, but approximating with time.Now for now
// {{ .podUnixStartTime }}: The pod creation time (in unix seconds, not millis)
// {{ .podUnixFinishTime }}: Don't have a good mechanism for this yet, but approximating with time.Now for now
type TemplateLogPlugin struct {
Expand All @@ -30,28 +32,32 @@ type regexValPair struct {
}

type templateRegexes struct {
PodName *regexp.Regexp
PodUID *regexp.Regexp
Namespace *regexp.Regexp
ContainerName *regexp.Regexp
ContainerID *regexp.Regexp
LogName *regexp.Regexp
Hostname *regexp.Regexp
PodUnixStartTime *regexp.Regexp
PodUnixFinishTime *regexp.Regexp
PodName *regexp.Regexp
PodUID *regexp.Regexp
Namespace *regexp.Regexp
ContainerName *regexp.Regexp
ContainerID *regexp.Regexp
LogName *regexp.Regexp
Hostname *regexp.Regexp
PodRFC3339StartTime *regexp.Regexp
PodRFC3339FinishTime *regexp.Regexp
PodUnixStartTime *regexp.Regexp
PodUnixFinishTime *regexp.Regexp
}

func mustInitTemplateRegexes() templateRegexes {
return templateRegexes{
PodName: mustCreateRegex("podName"),
PodUID: mustCreateRegex("podUID"),
Namespace: mustCreateRegex("namespace"),
ContainerName: mustCreateRegex("containerName"),
ContainerID: mustCreateRegex("containerID"),
LogName: mustCreateRegex("logName"),
Hostname: mustCreateRegex("hostname"),
PodUnixStartTime: mustCreateRegex("podUnixStartTime"),
PodUnixFinishTime: mustCreateRegex("podUnixFinishTime"),
PodName: mustCreateRegex("podName"),
PodUID: mustCreateRegex("podUID"),
Namespace: mustCreateRegex("namespace"),
ContainerName: mustCreateRegex("containerName"),
ContainerID: mustCreateRegex("containerID"),
LogName: mustCreateRegex("logName"),
Hostname: mustCreateRegex("hostname"),
PodRFC3339StartTime: mustCreateRegex("podRFC3339StartTime"),
PodRFC3339FinishTime: mustCreateRegex("podRFC3339FinishTime"),
PodUnixStartTime: mustCreateRegex("podUnixStartTime"),
PodUnixFinishTime: mustCreateRegex("podUnixFinishTime"),
}
}

Expand All @@ -69,16 +75,18 @@ func replaceAll(template string, values []regexValPair) string {
return template
}

func (s TemplateLogPlugin) GetTaskLog(podName, podUID, namespace, containerName, containerID, logName string, podUnixStartTime, podUnixFinishTime int64) (core.TaskLog, error) {
func (s TemplateLogPlugin) GetTaskLog(podName, podUID, namespace, containerName, containerID, logName string, podRFC3339StartTime string, podRFC3339FinishTime string, podUnixStartTime, podUnixFinishTime int64) (core.TaskLog, error) {
o, err := s.GetTaskLogs(Input{
LogName: logName,
Namespace: namespace,
PodName: podName,
PodUID: podUID,
ContainerName: containerName,
ContainerID: containerID,
PodUnixStartTime: podUnixStartTime,
PodUnixFinishTime: podUnixFinishTime,
LogName: logName,
Namespace: namespace,
PodName: podName,
PodUID: podUID,
ContainerName: containerName,
ContainerID: containerID,
PodRFC3339StartTime: podRFC3339StartTime,
PodRFC3339FinishTime: podRFC3339FinishTime,
PodUnixStartTime: podUnixStartTime,
PodUnixFinishTime: podUnixFinishTime,
})

if err != nil || len(o.TaskLogs) == 0 {
Expand Down Expand Up @@ -131,6 +139,14 @@ func (s TemplateLogPlugin) GetTaskLogs(input Input) (Output, error) {
regex: regexes.Hostname,
val: input.HostName,
},
{
regex: regexes.PodRFC3339StartTime,
val: input.PodRFC3339StartTime,
},
{
regex: regexes.PodRFC3339FinishTime,
val: input.PodRFC3339FinishTime,
},
{
regex: regexes.PodUnixStartTime,
val: strconv.FormatInt(input.PodUnixStartTime, 10),
Expand Down Expand Up @@ -160,6 +176,8 @@ func (s TemplateLogPlugin) GetTaskLogs(input Input) (Output, error) {
// {{ .containerId }}: The container id docker/crio generated at run time,
// {{ .logName }}: A deployment specific name where to expect the logs to be.
// {{ .hostname }}: The hostname where the pod is running and where logs reside.
// {{ .PodRFC3339StartTime }}: The pod creation time in RFC3339 format
// {{ .PodRFC3339FinishTime }}: Don't have a good mechanism for this yet, but approximating with time.Now for now
// {{ .podUnixStartTime }}: The pod creation time (in unix seconds, not millis)
// {{ .podUnixFinishTime }}: Don't have a good mechanism for this yet, but approximating with time.Now for now
func NewTemplateLogPlugin(templateUris []string, messageFormat core.TaskLog_MessageFormat) TemplateLogPlugin {
Expand Down
143 changes: 94 additions & 49 deletions go/tasks/pluginmachinery/tasklog/template_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ func TestTemplateLog(t *testing.T) {
"spark-kubernetes-driver",
"cri-o://abc",
"main_logs",
"2015-03-14T17:08:14+01:00",
"2021-06-15T20:47:57+02:00",
1426349294,
1623782877,
)
Expand All @@ -41,14 +43,16 @@ func Test_templateLogPlugin_Regression(t *testing.T) {
messageFormat core.TaskLog_MessageFormat
}
type args struct {
podName string
podUID string
namespace string
containerName string
containerID string
logName string
podUnixStartTime int64
podUnixFinishTime int64
podName string
podUID string
namespace string
containerName string
containerID string
logName string
podRFC3339StartTime string
podRFC3339FinishTime string
podUnixStartTime int64
podUnixFinishTime int64
}
tests := []struct {
name string
Expand All @@ -64,14 +68,16 @@ func Test_templateLogPlugin_Regression(t *testing.T) {
messageFormat: core.TaskLog_JSON,
},
args{
podName: "f-uuid-driver",
podUID: "pod-uid",
namespace: "flyteexamples-production",
containerName: "spark-kubernetes-driver",
containerID: "cri-o://abc",
logName: "main_logs",
podUnixStartTime: 123,
podUnixFinishTime: 12345,
podName: "f-uuid-driver",
podUID: "pod-uid",
namespace: "flyteexamples-production",
containerName: "spark-kubernetes-driver",
containerID: "cri-o://abc",
logName: "main_logs",
podRFC3339StartTime: "1970-01-01T01:02:03+01:00",
podRFC3339FinishTime: "1970-01-01T04:25:45+01:00",
podUnixStartTime: 123,
podUnixFinishTime: 12345,
},
core.TaskLog{
Uri: "https://console.aws.amazon.com/cloudwatch/home?region=us-east-1#logEventViewer:group=/flyte-production/kubernetes;stream=var.log.containers.f-uuid-driver_flyteexamples-production_spark-kubernetes-driver-abc.log",
Expand All @@ -87,14 +93,16 @@ func Test_templateLogPlugin_Regression(t *testing.T) {
messageFormat: core.TaskLog_JSON,
},
args{
podName: "podName",
podUID: "pod-uid",
namespace: "flyteexamples-production",
containerName: "spark-kubernetes-driver",
containerID: "cri-o://abc",
logName: "main_logs",
podUnixStartTime: 123,
podUnixFinishTime: 12345,
podName: "podName",
podUID: "pod-uid",
namespace: "flyteexamples-production",
containerName: "spark-kubernetes-driver",
containerID: "cri-o://abc",
logName: "main_logs",
podRFC3339StartTime: "1970-01-01T01:02:03+01:00",
podRFC3339FinishTime: "1970-01-01T04:25:45+01:00",
podUnixStartTime: 123,
podUnixFinishTime: 12345,
},
core.TaskLog{
Uri: "https://console.cloud.google.com/logs/viewer?project=test-gcp-project&angularJsUrl=%2Flogs%2Fviewer%3Fproject%3Dtest-gcp-project&resource=aws_ec2_instance&advancedFilter=resource.labels.pod_name%3DpodName",
Expand All @@ -110,14 +118,16 @@ func Test_templateLogPlugin_Regression(t *testing.T) {
messageFormat: core.TaskLog_JSON,
},
args{
podName: "flyteexamples-development-task-name",
podUID: "pod-uid",
namespace: "flyteexamples-development",
containerName: "ignore",
containerID: "ignore",
logName: "main_logs",
podUnixStartTime: 123,
podUnixFinishTime: 12345,
podName: "flyteexamples-development-task-name",
podUID: "pod-uid",
namespace: "flyteexamples-development",
containerName: "ignore",
containerID: "ignore",
logName: "main_logs",
podRFC3339StartTime: "1970-01-01T01:02:03+01:00",
podRFC3339FinishTime: "1970-01-01T04:25:45+01:00",
podUnixStartTime: 123,
podUnixFinishTime: 12345,
},
core.TaskLog{
Uri: "https://dashboard.k8s.net/#!/log/flyteexamples-development/flyteexamples-development-task-name/pod?namespace=flyteexamples-development",
Expand All @@ -134,7 +144,7 @@ func Test_templateLogPlugin_Regression(t *testing.T) {
messageFormat: tt.fields.messageFormat,
}

got, err := s.GetTaskLog(tt.args.podName, tt.args.podUID, tt.args.namespace, tt.args.containerName, tt.args.containerID, tt.args.logName, tt.args.podUnixStartTime, tt.args.podUnixFinishTime)
got, err := s.GetTaskLog(tt.args.podName, tt.args.podUID, tt.args.namespace, tt.args.containerName, tt.args.containerID, tt.args.logName, tt.args.podRFC3339FinishTime, tt.args.podRFC3339FinishTime, tt.args.podUnixStartTime, tt.args.podUnixFinishTime)
if (err != nil) != tt.wantErr {
t.Errorf("GetTaskLog() error = %v, wantErr %v", err, tt.wantErr)
return
Expand Down Expand Up @@ -170,14 +180,16 @@ func TestTemplateLogPlugin_NewTaskLog(t *testing.T) {
},
args{
input: Input{
HostName: "my-host",
PodName: "my-pod",
Namespace: "my-namespace",
ContainerName: "my-container",
ContainerID: "ignore",
LogName: "main_logs",
PodUnixStartTime: 123,
PodUnixFinishTime: 12345,
HostName: "my-host",
PodName: "my-pod",
Namespace: "my-namespace",
ContainerName: "my-container",
ContainerID: "ignore",
LogName: "main_logs",
PodRFC3339StartTime: "1970-01-01T01:02:03+01:00",
PodRFC3339FinishTime: "1970-01-01T04:25:45+01:00",
PodUnixStartTime: 123,
PodUnixFinishTime: 12345,
},
},
Output{
Expand All @@ -199,14 +211,16 @@ func TestTemplateLogPlugin_NewTaskLog(t *testing.T) {
},
args{
input: Input{
HostName: "my-host",
PodName: "my-pod",
Namespace: "my-namespace",
ContainerName: "my-container",
ContainerID: "ignore",
LogName: "main_logs",
PodUnixStartTime: 123,
PodUnixFinishTime: 12345,
HostName: "my-host",
PodName: "my-pod",
Namespace: "my-namespace",
ContainerName: "my-container",
ContainerID: "ignore",
LogName: "main_logs",
PodRFC3339StartTime: "1970-01-01T01:02:03+01:00",
PodRFC3339FinishTime: "1970-01-01T04:25:45+01:00",
PodUnixStartTime: 123,
PodUnixFinishTime: 12345,
},
},
Output{
Expand All @@ -220,6 +234,37 @@ func TestTemplateLogPlugin_NewTaskLog(t *testing.T) {
},
false,
},
{
"stackdriver-with-rfc3339-timestamp",
fields{
templateURI: "https://console.cloud.google.com/logs/viewer?project=test-gcp-project&angularJsUrl=%2Flogs%2Fviewer%3Fproject%3Dtest-gcp-project&resource=aws_ec2_instance&advancedFilter=resource.labels.pod_name%3D{{.podName}}%20%22{{.podRFC3339StartTime}}%22",
messageFormat: core.TaskLog_JSON,
},
args{
input: Input{
HostName: "my-host",
PodName: "my-pod",
Namespace: "my-namespace",
ContainerName: "my-container",
ContainerID: "ignore",
LogName: "main_logs",
PodRFC3339StartTime: "1970-01-01T01:02:03+01:00",
PodRFC3339FinishTime: "1970-01-01T04:25:45+01:00",
PodUnixStartTime: 123,
PodUnixFinishTime: 12345,
},
},
Output{
TaskLogs: []*core.TaskLog{
{
Uri: "https://console.cloud.google.com/logs/viewer?project=test-gcp-project&angularJsUrl=%2Flogs%2Fviewer%3Fproject%3Dtest-gcp-project&resource=aws_ec2_instance&advancedFilter=resource.labels.pod_name%3Dmy-pod%20%221970-01-01T01:02:03+01:00%22",
MessageFormat: core.TaskLog_JSON,
Name: "main_logs",
},
},
},
false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand Down

0 comments on commit 53e63bc

Please sign in to comment.