• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

dgraph-io / dgraph / 5220703043

09 Jun 2023 10:03AM UTC coverage: 67.312%. First build
5220703043

push

web-flow
Merge 75092fe35 into 95d888b64

58444 of 86825 relevant lines covered (67.31%)

2245062.62 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/dgraph/cmd/debuginfo/debugging.go
1
/*
2
 * Copyright 2019-2023 Dgraph Labs, Inc. and Contributors
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 *     http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16

17
package debuginfo
18

19
import (
20
        "fmt"
21
        "io"
22
        "net/http"
23
        "net/url"
24
        "os"
25
        "strings"
26
        "time"
27

28
        "github.com/golang/glog"
29
)
30

31
func saveMetrics(addr, pathPrefix string, seconds uint32, metricTypes []string) {
×
32
        u, err := url.Parse(addr)
×
33
        if err != nil || (u.Host == "" && u.Scheme != "" && u.Scheme != "file") {
×
34
                u, err = url.Parse("http://" + addr)
×
35
        }
×
36
        if err != nil || u.Host == "" {
×
37
                glog.Errorf("error while parsing address %s: %s", addr, err)
×
38
                return
×
39
        }
×
40

41
        duration := time.Duration(seconds) * time.Second
×
42

×
43
        for _, metricType := range metricTypes {
×
44
                source := u.String() + metricMap[metricType]
×
45
                switch metricType {
×
46
                case "cpu":
×
47
                        source += fmt.Sprintf("%s%d", "?seconds=", seconds)
×
48
                case "trace":
×
49
                        source += fmt.Sprintf("%s%d", "?seconds=", seconds)
×
50
                }
51
                savePath := fmt.Sprintf("%s%s.gz", pathPrefix, metricType)
×
52
                if err := saveDebug(source, savePath, duration); err != nil {
×
53
                        glog.Errorf("error while saving metric from %s: %s", source, err)
×
54
                        continue
×
55
                }
56

57
                glog.Infof("saving %s metric in %s", metricType, savePath)
×
58
        }
59
}
60

61
// saveDebug writes the debug info specified in the argument fetching it from the host
62
// provided in the configuration
63
func saveDebug(sourceURL, filePath string, duration time.Duration) error {
×
64
        var err error
×
65
        var resp io.ReadCloser
×
66

×
67
        glog.Infof("fetching information over HTTP from %s", sourceURL)
×
68
        if duration > 0 {
×
69
                glog.Info(fmt.Sprintf("please wait... (%v)", duration))
×
70
        }
×
71

72
        timeout := duration + duration/2 + 2*time.Second
×
73
        resp, err = fetchURL(sourceURL, timeout)
×
74
        if err != nil {
×
75
                return err
×
76
        }
×
77
        defer func() {
×
78
                if err := resp.Close(); err != nil {
×
79
                        glog.Warningf("error closing resp reader: %v", err)
×
80
                }
×
81
        }()
82

83
        out, err := os.Create(filePath)
×
84
        if err != nil {
×
85
                return fmt.Errorf("error while creating debug file: %s", err)
×
86
        }
×
87
        _, err = io.Copy(out, resp)
×
88
        return err
×
89
}
90

91
// fetchURL fetches a profile from a URL using HTTP.
92
func fetchURL(source string, timeout time.Duration) (io.ReadCloser, error) {
×
93
        client := &http.Client{
×
94
                Timeout: timeout,
×
95
        }
×
96
        resp, err := client.Get(source)
×
97
        if err != nil {
×
98
                return nil, fmt.Errorf("http fetch: %v", err)
×
99
        }
×
100
        if resp.StatusCode != http.StatusOK {
×
101
                defer func() {
×
102
                        if err := resp.Body.Close(); err != nil {
×
103
                                glog.Warningf("error closing body: %v", err)
×
104
                        }
×
105
                }()
106
                return nil, statusCodeError(resp)
×
107
        }
108

109
        return resp.Body, nil
×
110
}
111

112
func statusCodeError(resp *http.Response) error {
×
113
        if resp.Header.Get("X-Go-Pprof") != "" &&
×
114
                strings.Contains(resp.Header.Get("Content-Type"), "text/plain") {
×
115
                if body, err := io.ReadAll(resp.Body); err == nil {
×
116
                        return fmt.Errorf("server response: %s - %s", resp.Status, body)
×
117
                }
×
118
        }
119
        return fmt.Errorf("server response: %s", resp.Status)
×
120
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc