Go - How can I make sure there aren't empty fields being sent in this code via gRPC?

Viewed 1731

I am writing some code to send logs with gRPC to a server. The problem I'm having is that the logs are different and not all have every field, but . I'm wondering how I can set only the fields they do have inside logpb.Log short of creating several different types of logs in the proto file? This is all one methods, but the formatting on StackOverflow isn't with it. The code:

func (*Client) SendWithgRPC(entry *log.Entry) error {

conn, err := grpc.Dial("localhost:50051", grpc.WithInsecure())
if err != nil {
    log.Fatalf("Could not connect: %v", err)
}

defer conn.Close()

c := logpb.NewLogServiceClient(conn)

stream, err := c.SendLogs(context.Background())
if err != nil {
    log.Fatalf("Error while calling SendLogs: %v", err)
}

logFields := entry.Data

category := ""
debug_id := ""
request_id := ""
tipi := ""
uri := ""
var user_id int32 = 0
ip := ""

if logFields["category"] != nil {
    category = logFields["category"].(string)
}

if logFields["debug_id"] != nil {
    debug_id = logFields["debug_id"].(string)
}

if logFields["request_id"] != nil {
    request_id = logFields["request_id"].(string)
}

if logFields["type"] != nil {
    tipi = logFields["type"].(string)
}

if logFields["uri"] != nil {
    uri = logFields["uri"].(string)
}

if logFields["user_id"] != nil {
    user_id = int32(logFields["user_id"].(int))
}

if logFields["ip"] != nil {
    ip = logFields["ip"].(string)
}

logEntry := &logpb.Log{
    Time:      entry.Time.String(),
    Level:     entry.Level.String(),
    Msg:       entry.Message,
    Category:  category,
    DebugId:   debug_id,
    Ip:        ip,
    RequestId: request_id,
    Type:      tipi,
    Uri:       uri,
    Id:        user_id,
}

logs := []*logpb.Log{logEntry}
logarray := []*logpb.SendLogsRequest{
    &logpb.SendLogsRequest{
        Logs: logs,
    },
}

fmt.Print(logarray)

for _, req := range logarray {
    stream.Send(req)
}

_, err = stream.CloseAndRecv()
if err != nil {
    fmt.Printf("Error with response: %v", err)
}
return nil
}
1 Answers

You can use something like https://github.com/go-playground/validator
It offers validation using tags. There is a lot more to this lib apart from basic validation. Do check it out.
Sample example https://github.com/go-playground/validator/blob/master/_examples/simple/main.go

As easy as it gets :

package main

import (
    "fmt"
    "github.com/go-playground/validator/v10"
)

type Name struct {
    First string `validate:"required"`
    Last  string
}

func main() {
    validName := Name{First: "John"} // Last name is empty and is not required
    invalidName := Name{Last: "Doe"} // first name is empty but is required

    validate := validator.New()

    err := validate.Struct(invalidName)
    if err != nil {
        fmt.Println("invalid name struct caused error")
    }

    err = validate.Struct(validName)
    if err != nil {
        fmt.Println("valid name struct caused error")
    }

    fmt.Println("GoodBye")
}

The output of above :

invalid name struct caused error
GoodBye

working code on go-playground : https://play.golang.org/p/S4Yj1yr16t2

Related