[go] 파일에 로그를 쓰는 방법

Go로 로그 파일에 쓰려고합니다.

나는 여러 가지 접근법을 시도했지만 모두 실패했습니다. 이것이 내가 시도한 것입니다.

func TestLogging(t *testing.T) {
    if !FileExists("logfile") {
        CreateFile("logfile")
    }
    f, err := os.Open("logfile")
    if err != nil {
        t.Fatalf("error: %v", err)
    }

    // attempt #1
    log.SetOutput(io.MultiWriter(os.Stderr, f))
    log.Println("hello, logfile")

    // attempt #2
    log.SetOutput(io.Writer(f))
    log.Println("hello, logfile")

    // attempt #3
    log.SetOutput(f)
    log.Println("hello, logfile")
}

func FileExists(name string) bool {
    if _, err := os.Stat(name); err != nil {
       if os.IsNotExist(err) {
            return false
        }
    }
    return true
}

func CreateFile(name string) error {
    fo, err := os.Create(name)
    if err != nil {
        return err
    }
    defer func() {
        fo.Close()
    }()
    return nil
}

로그 파일이 생성되지만 아무것도 인쇄되거나 추가되지 않습니다. 왜?



답변

os.Open() 과거에는 다르게 작동 했음에 틀림없지 만 이것은 나를 위해 작동합니다.

f, err := os.OpenFile("testlogfile", os.O_RDWR | os.O_CREATE | os.O_APPEND, 0666)
if err != nil {
    log.Fatalf("error opening file: %v", err)
}
defer f.Close()

log.SetOutput(f)
log.Println("This is a test log entry")

Go 문서에 따르면 “읽기 용”파일이 열리기 때문에 에서 os.Open()사용할 수 없습니다 log.SetOutput.

func Open

func Open(name string) (file *File, err error) Open읽기 위해 명명 된 파일을 엽니 다. 성공하면 반환 된 파일의 메서드를 사용하여 읽을 수 있습니다. 연관된 파일 설명자에는 mode가 있습니다 O_RDONLY. 오류가있는 경우 유형이 *PathError됩니다.

편집하다

확인 defer f.Close()후 이동if err != nil


답변

로깅을위한 12 단계 앱 권장 사항의 단순성과 유연성을 선호합니다. 로그 파일에 추가하려면 셸 리디렉션을 사용할 수 있습니다. Go의 기본 로거는 stderr (2)에 기록합니다.

./app 2>> logfile

참조 : http://12factor.net/logs


답변

나는 보통 화면에 로그를 인쇄하고 파일에도 씁니다. 이것이 누군가를 돕기를 바랍니다.

f, err := os.OpenFile("/tmp/orders.log", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
if err != nil {
    log.Fatalf("error opening file: %v", err)
}
defer f.Close()
wrt := io.MultiWriter(os.Stdout, f)
log.SetOutput(wrt)
log.Println(" Orders API Called")


답변

이것은 나를 위해 작동합니다

  1. logger.go라는 패키지를 만들었습니다.

    package logger
    
    import (
      "flag"
      "os"
      "log"
      "go/build"
    )
    
    var (
      Log      *log.Logger
    )
    
    
    func init() {
        // set location of log file
        var logpath = build.Default.GOPATH + "/src/chat/logger/info.log"
    
       flag.Parse()
       var file, err1 = os.Create(logpath)
    
       if err1 != nil {
          panic(err1)
       }
          Log = log.New(file, "", log.LstdFlags|log.Lshortfile)
          Log.Println("LogFile : " + logpath)
    }
    1. 로그하려는 위치에 패키지를 가져옵니다 (예 : main.go).

      package main
      
      import (
         "logger"
      )
      
      const (
         VERSION = "0.13"
       )
      
      func main() {
      
          // time to use our logger, print version, processID and number of running process
          logger.Log.Printf("Server v%s pid=%d started with processes: %d", VERSION, os.Getpid(),runtime.GOMAXPROCS(runtime.NumCPU()))
      
      }

답변

리눅스 머신에서 바이너리를 실행한다면 쉘 스크립트를 사용할 수 있습니다.

파일로 덮어 쓰기

./binaryapp > binaryapp.log

파일에 추가

./binaryapp >> binaryapp.log

stderr을 파일로 덮어 쓰기

./binaryapp &> binaryapp.error.log

파일에 stderr 추가

./binaryapp &>> binalyapp.error.log

쉘 스크립트 파일을 사용하면 더 동적 일 수 있습니다.


답변

Go의 기본 로거는 stderr (2)에 기록합니다. 파일로 리디렉션

import (
    "syscall"
    "os"
 )
func main(){
  fErr, err = os.OpenFile("Errfile", os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600)
  syscall.Dup2(int(fErr.Fd()), 1) /* -- stdout */
  syscall.Dup2(int(fErr.Fd()), 2) /* -- stderr */

}


답변

var필요한 경우 모든 프로세스가 액세스 할 수 있도록 전역에서 최상위를 선언하십시오 .

package main

import (
    "log"
    "os"
)
var (
    outfile, _ = os.Create("path/to/my.log") // update path for your needs
    l      = log.New(outfile, "", 0)
)

func main() {
    l.Println("hello, log!!!")
}