在字符串中插入变量

时间:2018-11-11 13:59:20

标签: json go struct

我有一个hostname和一个json格式的字符串。我想在该hostname格式的字符串的键的值字符串中插入json

我的完整代码:

func pager() string {
token := "xxxxxxxxxxx"
url := "https://api.pagerduty.com/incidents"
hostname, err := os.Hostname()
fmt.Println(hostname, err)

jsonStr := []byte(`{
    "incident": {
        "type": "incident",
        **"title": "Docker is down on."+hostname,**
        "service": {
          "id": "PWIXJZS",
          "type": "service_reference"
        },
        "priority": {
          "id": "P53ZZH5",
          "type": "priority_reference"
        },
        "urgency": "high",
        "incident_key": "baf7cf21b1da41b4b0221008339ff357",
        "body": {
          "type": "incident_body",
          "details": "A disk is getting full on this machine. You should investigate what is causing the disk to fill, and ensure that there is an automated process in place for ensuring data is rotated (eg. logs should have logrotate around them). If data is expected to stay on this disk forever, you should start planning to scale up to a larger disk."
        },
        "escalation_policy": {
          "id": "PT20YPA",
          "type": "escalation_policy_reference"
        }
    }
}`)

req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonStr))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Accept", "application/vnd.pagerduty+json;version=2")
req.Header.Set("From", "shinoda@wathever.com")
req.Header.Set("Authorization", "Token token="+token)

client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
    panic(err)
}

return resp.Status
}

func main() {
    fmt.Println(pager())

}

我对go不太熟悉,在python中我可以轻松地做到这一点,我不知道在golang中执行此操作的正确方法。

如果有人可以解释我,我将不胜感激。

提前谢谢。

4 个答案:

答案 0 :(得分:1)

创建一个结构以表示json

type 
    Incident struct {
        Type    string `json:"type"`
        Title   string `json:"title"`
        Service struct {
            ID   string `json:"id"`
            Type string `json:"type"`
        } `json:"service"`
        Priority struct {
            ID   string `json:"id"`
            Type string `json:"type"`
        } `json:"priority"`
        Urgency     string `json:"urgency"`
        IncidentKey string `json:"incident_key"`
        Body        struct {
            Type    string `json:"type"`
            Details string `json:"details"`
        } `json:"body"`
        EscalationPolicy struct {
            ID   string `json:"id"`
            Type string `json:"type"`
        } `json:"escalation_policy"`
}

然后做类似的事情

hostname,err:=os.Hostname()
if (err !=nil) {
   panic(err)
}
incident:=Incident{ Type: "incident",
                    Title: fmt.Sprintf("Docker is down on %s", hostname),
                    //...etc etc add all other fields

req, err := http.NewRequest("POST", url, json.Marshal(incident))

在结构内部声明结构的变通方法似乎有点笨拙(抱歉)

Service: struct {
            ID   string `json:"id"`
            Type string `json:"type"`
        }{
            ID: "asdf",
            Type: "ABC",
       },

另一个答案https://stackoverflow.com/a/53255390/1153938显示了如何在事件结构中拆分结构,这是一种更干净的方法

我将在此处保留此答案,因为如何以这种方式声明它可能很有趣

如果您仅调用json.Unmarshal,则这种方法会很好,但是可以根据需要在程序中声明内容,也许不是最好的方法

答案 1 :(得分:0)

问题就像正确地引用字符串一样简单。这应该可以解决您眼前的问题:

jsonStr := []byte(`{
    "incident": {
        "type": "incident",
        "title": "Docker is down on `+hostname+`",
        "service": {
          "id": "PWIXJZS",
          "type": "service_reference"
        },
        "priority": {
          "id": "P53ZZH5",
          "type": "priority_reference"
        },
        "urgency": "high",
        "incident_key": "baf7cf21b1da41b4b0221008339ff357",
        "body": {
          "type": "incident_body",
          "details": "A disk is getting full on this machine. You should investigate what is causing the disk to fill, and ensure that there is an automated process in place for ensuring data is rotated (eg. logs should have logrotate around them). If data is expected to stay on this disk forever, you should start planning to scale up to a larger disk."
        },
        "escalation_policy": {
          "id": "PT20YPA",
          "type": "escalation_policy_reference"
        }
    }
}`)

但是@Vorsprung建议的一种更好的方法是使用适当的Go数据结构,并将其封送为JSON。

答案 2 :(得分:0)

尝试以下解决方案:

hostname, err := os.Hostname()
if err != nil {
    // handle err
}

indent := fmt.Sprintf(`{
    "incident": {
        "type": "incident",
        "title": "Docker is down on %s",
        "service": {
          "id": "PWIXJZS",
          "type": "service_reference"
        },
        "priority": {
          "id": "P53ZZH5",
          "type": "priority_reference"
        },
        "urgency": "high",
        "incident_key": "baf7cf21b1da41b4b0221008339ff357",
        "body": {
          "type": "incident_body",
          "details": "A disk is getting full on this machine. You should investigate what is causing the disk to fill, and ensure that there is an automated process in place for ensuring data is rotated (eg. logs should have logrotate around them). If data is expected to stay on this disk forever, you should start planning to scale up to a larger disk."
        },
        "escalation_policy": {
          "id": "PT20YPA",
          "type": "escalation_policy_reference"
        }
    }
}`, hostname)
jsonStr := []byte(indent)

答案 3 :(得分:0)

以@Vorsprung的响应为基础,除非我弄错了,否则您可能需要对结构进行一些不同的定义,以避免基于response遇到的错误 在事件上初始化并填充了必需的属性后,您应该可以在对该对象执行json.Marshal()之后发布该对象。

jsonObject, _ := json.MarshalIndent(someIncident, "", "\t")

如果要在此软件包之外使用这些结构,则可能需要将名称更改为大写以允许导出。

type incident struct {
    Type             string           `json:"type"`
    Title            string           `json:"title"`
    Service          service          `json:"service"`
    Priority         priority         `json:"priority"`
    Urgency          string           `json:"urgency"`
    IncidentKey      string           `json:"incident_key"`
    Body             body             `json:"body"`
    EscalationPolicy escalationPolicy `json:"escalation_policy"`
}

type service struct {
    ID   string `json:"id"`
    Type string `json:"type"`
}

type priority struct {
    ID   string `json:"id"`
    Type string `json:"type"`
}

type body struct {
    Type    string `json:"type"`
    Details string `json:"details"`
}

type escalationPolicy struct {
    ID   string `json:"id"`
    Type string `json:"type"`
}

对象的初始化:

someIncident := incident{
    Type:  "SomeType",
    Title: "SomeTitle",
    Service: service{
        ID:   "SomeId",
        Type: "SomeType"},
    Priority: priority{
        ID:   "SomeId",
        Type: "SomeType"},
    Urgency:     "SomeUrgency",
    IncidentKey: "SomeKey",
    Body: body{
        Type:    "SomeType",
        Details: "SomeDetails"},
    EscalationPolicy: escalationPolicy{
        ID:   "SomeId",
        Type: "SomeType"}}