Created
January 5, 2017 09:54
-
-
Save alwqx/b1f93ccadaa4d9f4970ec1538bb8ca9a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"bytes" | |
"encoding/json" | |
"fmt" | |
client "github.com/docker/engine-api/client" | |
"github.com/docker/engine-api/types" | |
"log" | |
"os" | |
"runtime" | |
"strconv" | |
"time" | |
//"golang.org/x/net/context" | |
"context" | |
"github.com/spf13/cobra" | |
"net/http" | |
_ "net/http/pprof" | |
) | |
func main() { | |
var interval int | |
rootCmd := &cobra.Command{ | |
Use: "Goroutine leak debug", | |
Short: "debug goroutine leak", | |
Run: func(cmd *cobra.Command, args []string) { | |
if runtime.GOOS != "linux" { | |
fmt.Println("From linux for now, application exit.") | |
return | |
} | |
debugHttp() | |
for { | |
containerLogsInfo := GetContainerLogsInfo(int64(interval)) | |
fmt.Println(len(containerLogsInfo)) | |
if interval == 0 { | |
return | |
} | |
time.Sleep(time.Millisecond * time.Duration(interval)) | |
} | |
}, | |
} | |
rootCmd.Flags().IntVarP(&interval, "interval", "i", 0, "Interval to retrieval data(millisecond), default 0 is not repeat.") | |
rootCmd.Execute() | |
} | |
type ContainerLogs struct { | |
ID string `json:"id"` | |
Names []string `json:"name"` | |
Image string `json:"image"` | |
Log string `json:"log"` | |
} | |
type ContainerLogsInfo struct { | |
Timestamp int64 `json:"timestamp"` | |
MachineID string `json:"machine_id"` | |
LogList []ContainerLogs `json:"log_list"` | |
} | |
func GetContainers() ([]types.Container, error) { | |
ctx, cancel := context.WithTimeout(context.Background(), 50*time.Millisecond) | |
defer cancel() | |
cli, err := client.NewEnvClient() | |
if err != nil { | |
return nil, err | |
} | |
containers, err := cli.ContainerList(ctx, types.ContainerListOptions{}) | |
return containers, err | |
} | |
func GetContainerLogByID(ID string, opts types.ContainerLogsOptions) string { | |
ctx, cancel := context.WithTimeout(context.Background(), 50*time.Millisecond) | |
defer cancel() | |
cli, err := client.NewEnvClient() | |
if err != nil { | |
log.Fatal(err) | |
} | |
reader, err := cli.ContainerLogs(ctx, ID, opts) | |
if err != nil { | |
log.Fatal(err) | |
} | |
buf := new(bytes.Buffer) | |
buf.ReadFrom(reader) | |
return buf.String() | |
} | |
func GetContainerLogsInfo(interval int64) string { | |
containers, err := GetContainers() | |
if err != nil { | |
log.Fatal("Get containers error:", err) | |
return "" | |
} | |
var containerLogsInfo ContainerLogsInfo | |
containerLogsInfo.Timestamp = getUnixTimestamp() | |
containerLogsInfo.MachineID = getMachineID() | |
opts := types.ContainerLogsOptions{ | |
Since: timestampSubInterval(interval), | |
ShowStdout: true, | |
ShowStderr: true, | |
} | |
for _, container := range containers { | |
var containerLogs ContainerLogs | |
containerLogs.ID = container.ID | |
containerLogs.Names = container.Names | |
containerLogs.Image = container.Image | |
containerLogs.Log = GetContainerLogByID(container.ID, opts) | |
containerLogsInfo.LogList = append(containerLogsInfo.LogList, containerLogs) | |
} | |
retJson, err := json.Marshal(containerLogsInfo) | |
if err != nil { | |
log.Fatal("marshal json error:", err) | |
} | |
return string(retJson) | |
} | |
func getUnixTimestamp() int64 { | |
return time.Now().Unix() | |
} | |
func getMachineID() string { | |
//stdout, err := exec.Command("hostname").CombinedOutput() | |
h, err := os.Hostname() | |
if err != nil { | |
log.Println("hostname cannot retrieval.") | |
log.Println(err) | |
return "" | |
} | |
return h | |
} | |
func timestampSubInterval(interval int64) string { | |
//change interval from millsecond to second | |
delta := time.Now().Unix() - interval/1000 | |
return strconv.FormatInt(delta, 10) | |
} | |
func debugHttp() { | |
go func() { | |
log.Println(http.ListenAndServe("0.0.0.0:34888", nil)) | |
}() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment