|
|
|
@ -626,22 +626,26 @@ func (u *ContainerService) ContainerLogs(wsConn *websocket.Conn, containerType,
|
|
|
|
|
if cmd.CheckIllegal(container, since, tail) { |
|
|
|
|
return buserr.New(constant.ErrCmdIllegal) |
|
|
|
|
} |
|
|
|
|
command := fmt.Sprintf("docker logs %s", container) |
|
|
|
|
commandName := "docker" |
|
|
|
|
commandArg := []string{"logs", container} |
|
|
|
|
if containerType == "compose" { |
|
|
|
|
command = fmt.Sprintf("docker-compose -f %s logs", container) |
|
|
|
|
commandName = "docker-compose" |
|
|
|
|
commandArg = []string{"-f", container, "logs"} |
|
|
|
|
} |
|
|
|
|
if tail != "0" { |
|
|
|
|
command += " --tail " + tail |
|
|
|
|
commandArg = append(commandArg, "--tail") |
|
|
|
|
commandArg = append(commandArg, tail) |
|
|
|
|
} |
|
|
|
|
if since != "all" { |
|
|
|
|
command += " --since " + since |
|
|
|
|
commandArg = append(commandArg, "--since") |
|
|
|
|
commandArg = append(commandArg, since) |
|
|
|
|
} |
|
|
|
|
if follow { |
|
|
|
|
command += " -f" |
|
|
|
|
commandArg = append(commandArg, "-f") |
|
|
|
|
} |
|
|
|
|
command += " 2>&1" |
|
|
|
|
cmd := exec.Command("bash", "-c", command) |
|
|
|
|
if !follow { |
|
|
|
|
commandArg = append(commandArg, "2>&1") |
|
|
|
|
cmd := exec.Command(commandName, commandArg...) |
|
|
|
|
stdout, _ := cmd.CombinedOutput() |
|
|
|
|
if !utf8.Valid(stdout) { |
|
|
|
|
return errors.New("invalid utf8") |
|
|
|
@ -652,50 +656,52 @@ func (u *ContainerService) ContainerLogs(wsConn *websocket.Conn, containerType,
|
|
|
|
|
return nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
cmd := exec.Command(commandName, commandArg...) |
|
|
|
|
stdout, err := cmd.StdoutPipe() |
|
|
|
|
if err != nil { |
|
|
|
|
_ = cmd.Process.Signal(syscall.SIGTERM) |
|
|
|
|
return err |
|
|
|
|
} |
|
|
|
|
if err := cmd.Start(); err != nil { |
|
|
|
|
_ = cmd.Process.Signal(syscall.SIGTERM) |
|
|
|
|
return err |
|
|
|
|
} |
|
|
|
|
defer func() { |
|
|
|
|
_ = cmd.Process.Signal(syscall.SIGTERM) |
|
|
|
|
_ = cmd.Wait() |
|
|
|
|
exitCh := make(chan struct{}) |
|
|
|
|
go func() { |
|
|
|
|
_, wsData, _ := wsConn.ReadMessage() |
|
|
|
|
if string(wsData) == "close conn" { |
|
|
|
|
_ = cmd.Process.Signal(syscall.SIGTERM) |
|
|
|
|
exitCh <- struct{}{} |
|
|
|
|
} |
|
|
|
|
}() |
|
|
|
|
var exitCh chan struct{} |
|
|
|
|
if follow { |
|
|
|
|
go func() { |
|
|
|
|
_, wsData, _ := wsConn.ReadMessage() |
|
|
|
|
if string(wsData) == "close conn" { |
|
|
|
|
exitCh <- struct{}{} |
|
|
|
|
} |
|
|
|
|
}() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
buffer := make([]byte, 1024) |
|
|
|
|
for { |
|
|
|
|
select { |
|
|
|
|
case <-exitCh: |
|
|
|
|
return nil |
|
|
|
|
default: |
|
|
|
|
n, err := stdout.Read(buffer) |
|
|
|
|
if err != nil { |
|
|
|
|
if err == io.EOF { |
|
|
|
|
return err |
|
|
|
|
|
|
|
|
|
go func() { |
|
|
|
|
buffer := make([]byte, 1024) |
|
|
|
|
for { |
|
|
|
|
select { |
|
|
|
|
case <-exitCh: |
|
|
|
|
return |
|
|
|
|
default: |
|
|
|
|
n, err := stdout.Read(buffer) |
|
|
|
|
if err != nil { |
|
|
|
|
if err == io.EOF { |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
global.LOG.Errorf("read bytes from log failed, err: %v", err) |
|
|
|
|
continue |
|
|
|
|
} |
|
|
|
|
if !utf8.Valid(buffer[:n]) { |
|
|
|
|
continue |
|
|
|
|
} |
|
|
|
|
if err = wsConn.WriteMessage(websocket.TextMessage, buffer[:n]); err != nil { |
|
|
|
|
global.LOG.Errorf("send message with log to ws failed, err: %v", err) |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
global.LOG.Errorf("read bytes from log failed, err: %v", err) |
|
|
|
|
continue |
|
|
|
|
} |
|
|
|
|
if !utf8.Valid(buffer[:n]) { |
|
|
|
|
continue |
|
|
|
|
} |
|
|
|
|
if err = wsConn.WriteMessage(websocket.TextMessage, buffer[:n]); err != nil { |
|
|
|
|
global.LOG.Errorf("send message with log to ws failed, err: %v", err) |
|
|
|
|
return err |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
}() |
|
|
|
|
_ = cmd.Wait() |
|
|
|
|
return nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (u *ContainerService) ContainerStats(id string) (*dto.ContainerStats, error) { |
|
|
|
|