Skip to content

Logrus logs #423

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Mar 7, 2022
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ require (
github.com/hashicorp/terraform-plugin-sdk/v2 v2.8.0
github.com/rclone/rclone v1.57.0
github.com/sebdah/goldie/v2 v2.5.3
github.com/sirupsen/logrus v1.8.1
github.com/stretchr/testify v1.7.0
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5
golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f
Expand Down
8 changes: 7 additions & 1 deletion iterative/resource_task.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"

"terraform-provider-iterative/iterative/utils"
"terraform-provider-iterative/task"
"terraform-provider-iterative/task/common"
)
Expand Down Expand Up @@ -234,8 +235,13 @@ func resourceTaskRead(ctx context.Context, d *schema.ResourceData, m interface{}
return diagnostic(diags, err, diag.Warning)
}
d.Set("logs", logs)

d.SetId(task.GetIdentifier(ctx).Long())

logger := utils.TpiLogger(d)
logger.Info("instance")
logger.Info("logs")
logger.Info("status")

return diags
}

Expand Down
104 changes: 104 additions & 0 deletions iterative/utils/logger.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package utils

import (
"fmt"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/sirupsen/logrus"
"strings"
"time"
)

var baseTimestamp = time.Now()
var colors = make(map[string]int)

type basicFormatter struct{}

func (f *basicFormatter) Format(entry *logrus.Entry) ([]byte, error) {
levelText := strings.ToUpper(entry.Level.String())
levelColor := colors[levelText]
tpl := "[%s] 🚀\x1b[%dmTPI\x1b[0m %s\n"
return []byte(fmt.Sprintf(tpl, levelText, levelColor, entry.Message)), nil
}

func init() {
colors["DEBUG"] = 36
colors["INFO"] = 36
colors["WARN"] = 33
colors["ERROR"] = 31
colors["FATAL"] = 31
colors["purple"] = 35

logrus.SetLevel(logrus.DebugLevel)
logrus.SetFormatter(&basicFormatter{})
}

type tpiFormatter struct{}

func (f *tpiFormatter) Format(entry *logrus.Entry) ([]byte, error) {
data := make(logrus.Fields)
for k, v := range entry.Data {
data[k] = v
}

d := data["d"].(*schema.ResourceData)
message := entry.Message
levelText := strings.ToUpper(entry.Level.String())
levelColor := colors[levelText]

if message == "instance" {
cloud := d.Get("cloud").(string)
machine := d.Get("machine").(string)
region := d.Get("region").(string)
spot := d.Get("spot").(float64)

spottext := ""
if spot > 0 {
spottext = fmt.Sprintf("(Spot %f/h)", spot)
}
message = fmt.Sprintf("🚀 %s %s%s at %s", cloud, machine, spottext, region)
}

if message == "status" {
status := d.Get("status").(map[string]interface{})

running := "not yet started"
if status["running"] != nil {
running = "is terminated"
if status["running"].(int) == 1 {
running = "is running 🟡"
}
}

success := ""
if running == "is terminated" {
success = "without any output"
if status["succeeded"] != nil && status["succeeded"].(int) == 1 {
success = "succesfully 🟢"
}
if status["failed"] != nil && status["failed"].(int) == 1 {
success = "with errors 🔴"
}
}

message = fmt.Sprintf("Task %s %s", running, success)
}

if message == "logs" {
logs := d.Get("logs").([]interface{})
taskLogs := "No logs"
if len(logs) > 0 {
taskLogs = strings.Replace(logs[0].(string), "\n", fmt.Sprintf("\n[%s] ", levelText), -1)
}

message = fmt.Sprintf("Task logs:\x1b[%dm%s\x1b[0m", colors["purple"], taskLogs)
}

tpl := "[%s] \x1b[%dm🚀TPI %s\x1b[0m %s '\n"
return []byte(fmt.Sprintf(tpl, levelText, levelColor, d.Id(), message)), nil
}

func TpiLogger(d *schema.ResourceData) *logrus.Entry {
logrus.SetFormatter(&tpiFormatter{})

return logrus.WithFields(logrus.Fields{"d": d})
}
172 changes: 172 additions & 0 deletions iterative/utils/logger_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
package utils

import (
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

func TestState(t *testing.T) {
d := generateSchemaData(t, map[string]interface{}{
"name": "mytask",
"status": map[string]interface{}{
"running": 0,
"failed": 0,
},
})

logger := TpiLogger(d)
logger.Info("status")
}

func TestState2(t *testing.T) {
d := generateSchemaData(t, map[string]interface{}{
"name": "mytask",
"status": map[string]interface{}{
"running": 0,
"failed": 1,
},
})

logger := TpiLogger(d)
logger.Info("status")
}

func TestState3(t *testing.T) {
d := generateSchemaData(t, map[string]interface{}{
"name": "mytask",
"status": map[string]interface{}{
"running": 0,
"succeeded": 1,
},
})

logger := TpiLogger(d)
logger.Info("status")
}

func TestLogs(t *testing.T) {
logs := make([]interface{}, 0)
logs = append(logs, "-- Logs begin at Tue 2022-03-01 12:25:09 UTC, end at Tue 2022-03-01 12:30:30 UTC. --\nMar 01 12:25:50 tpi000000 systemd[1]: Started tpi-task.service.\nMar 01 12:25:50 tpi000000 sudo[1706]: root : TTY=unknown ; PWD=/tmp/tpi-task ; USER=root ; COMMAND=/usr/bin/apt update\nMar 01 12:25:50 tpi000000 sudo[1706]: pam_unix(sudo:session): session opened for user root by (uid=0)\nMar 01 12:25:50 tpi000000 tpi-task[1711]: WARNING: apt does not have a stable CLI interface. Use with caution in scripts.\nMar 01 12:25:50 tpi000000 tpi-task[1711]: Hit:1 http://azure.archive.ubuntu.com/ubuntu focal InRelease\nMar 01 12:25:50 tpi000000 tpi-task[1711]: Get:2 http://azure.archive.ubuntu.com/ubuntu focal-updates InRelease [114 kB]\nMar 01 12:25:50 tpi000000 tpi-task[1711]: Get:3 http://azure.archive.ubuntu.com/ubuntu focal-backports InRelease [108 kB]\nMar 01 12:25:51 tpi000000 tpi-task[1711]: Get:4 http://security.ubuntu.com/ubuntu focal-security InRelease [114 kB]\nMar 01 12:25:51 tpi000000 tpi-task[1711]: Get:5 http://azure.archive.ubuntu.com/ubuntu focal/universe amd64 Packages [8628 kB]\n")

d := generateSchemaData(t, map[string]interface{}{
"name": "mytask",
"logs": logs,
})

logger := TpiLogger(d)
logger.Info("logs")
}

func TestMachine(t *testing.T) {
d := generateSchemaData(t, map[string]interface{}{
"name": "mytask",
"cloud": "aws",
"machine": "t2.micro",
"spot": 0.2,
"region": "us-west",
})

logger := TpiLogger(d)
logger.Info("instance")
}

func generateSchemaData(t *testing.T, raw map[string]interface{}) *schema.ResourceData {
sch := map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
ForceNew: true,
Optional: true,
},
"cloud": {
Type: schema.TypeString,
ForceNew: true,
Required: true,
},
"region": {
Type: schema.TypeString,
ForceNew: true,
Optional: true,
Default: "us-west",
},
"machine": {
Type: schema.TypeString,
ForceNew: true,
Optional: true,
Default: "m",
},
"disk_size": {
Type: schema.TypeInt,
ForceNew: true,
Optional: true,
Default: 30,
},
"spot": {
Type: schema.TypeFloat,
ForceNew: true,
Optional: true,
Default: -1,
},
"image": {
Type: schema.TypeString,
ForceNew: true,
Optional: true,
Default: "ubuntu",
},
"addresses": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"status": {
Type: schema.TypeMap,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeInt,
},
},
"events": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"logs": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"script": {
Type: schema.TypeString,
ForceNew: true,
Required: true,
},
"workdir": {
Optional: true,
Type: schema.TypeSet,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"input": {
Type: schema.TypeString,
ForceNew: true,
Optional: true,
Default: "",
},
"output": {
Type: schema.TypeString,
ForceNew: false,
Optional: true,
Default: "",
},
},
},
},
}

return schema.TestResourceDataRaw(t, sch, raw)
}
Loading