Вставьте переменную внутри строки - PullRequest
0 голосов
/ 11 ноября 2018

У меня есть строка 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 голосов
/ 12 ноября 2018

Основываясь на ответе @ Vorsprung, если я не ошибаюсь, вы можете определить структуры немного по-другому, чтобы избежать ошибки, которую вы получаете, основываясь на вашем ответе После того, как вы инициализировали и заполнили обязательные свойства для инцидента, вы сможете POST-объект после выполнения 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"}}
0 голосов
/ 11 ноября 2018

Проблема так же проста, как и правильное цитирование строк. Это должно решить вашу непосредственную проблему:

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.

0 голосов
/ 11 ноября 2018

Попробуйте это решение:

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)
0 голосов
/ 11 ноября 2018

делает структуру в go для представления 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 показывает, как разделить структуры внутри структуры Incident, и является более чистым способом сделать это

Я оставлю этот ответ здесь, потому что может быть интересно, как его объявить таким образом

Если вы звоните только по номеру json.Unmarshal, тогда этот способ будет вполне подходящим, но для объявления вещей в программе, которые вам нужно сделать, возможно, не самый лучший

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...