Racket:记录到文件

时间:2016-08-26 12:39:34

标签: racket

我正在编写一个需要记录信息的Racket程序,但我想将日志存储在一个文件中。我的第一次尝试是使用“with-logging-to-port”并使用“open-output-file”来创建输出端口。

#lang racket
(require racket/logging)
(define (identity/log x)
  (log-info "returning ~a" x) x)

(with-logging-to-port (open-output-file "testing.txt")
  (λ () (identity/log 4)) 'info)

然而,当我打开文件后,它是空白的!另外,我不能多次运行这个,因为“open-output-file”给出了一个错误,该文件已经存在。

4 个答案:

答案 0 :(得分:3)

我很确定原因是您没有正确关闭文件。这应该有效:

(let ((out (open-output-file "testing.txt"
                             ; just to not get an error on consecutive runs
                             #:exists 'append))) 
  (with-logging-to-port out
    (λ () (identity/log 4)) 'info)
  (close-output-port out))

您可以使用call-with-output-file

而不是做家务
(call-with-output-file "testing.txt"
  (λ (out) 
    (with-logging-to-port out
      (λ () (identity/log 4)) 'info))
  #:exists 'append)

答案 1 :(得分:2)

我给你的日志功能来源:

(define my_logger (make-logger 'my-log))

(define logger_thread #f)

(define (log fmt . content)
  (log-message my_logger 'info "" (string-append (format-time (now)) " " (apply format (cons fmt content)))))

(define (start-logger log_path)
  (let ([r (make-log-receiver my_logger 'info)]
        [riqi (format-riqi (now))])
    (set! logger_thread
          (thread
           (lambda ()
             (let ([log_dir (build-path log_path (substring riqi 0 4))])
               (when (not (directory-exists? log_dir))
                 (make-directory log_dir))
               (with-output-to-file 
                   (build-path log_path (substring riqi 0 4) riqi) #:exists 'append
                   (lambda ()
                     (let loop ()
                       (match (sync r)
                         [(vector l m v v1)
                          (printf "~a\n" v)
                          (flush-output)])
                       (loop))))))))))

(define (restart-logger)
  (kill-thread logger_thread)
  (start-logger))

(define (launch-log-daemon log_path)
  (start-logger log_path)
  (thread
   (lambda ()
     (let loop ()
       (sync
        (alarm-evt (+ (current-inexact-milliseconds) (* 1000 60 60))))
       (when (= 0 (date-hour (seconds->date (current-seconds))))
         (restart-logger))
       (loop)))))

在应用程序的开头,您应该运行:

(launch-log-daemon log_path)

然后你可以像这样使用它:

(log "~a:~a" "some1" "some2")

我使用日期作为日志文件目录和名称,

当日期更改时,它会自动启动新的日志文件。

foramt-riqi和格式时间在这里:

(define (format-riqi the_date)
  (format "~a~a~a" 
          (date-year the_date) 
          (~a (date-month the_date) #:min-width 2 #:pad-string "0" #:align 'right)
          (~a (number->string (date-day the_date)) #:min-width 2 #:pad-string "0" #:align 'right)))

(define (format-time the_date)
  (format "~a:~a:~a" 
          (~a (date-hour the_date) #:min-width 2 #:pad-string "0" #:align 'right)
          (~a (date-minute the_date) #:min-width 2 #:pad-string "0" #:align 'right)
          (~a (date-second the_date) #:min-width 2 #:pad-string "0" #:align 'right)))

答案 2 :(得分:1)

使用标记'追加打开您的文件。例如:

    (open-output-file "testing.txt" #:exists 'append )

答案 3 :(得分:1)

如果日志信息在字符串列表中,比如lst,还可以使用以下函数:

(display-lines-to-file  lst "mylog.txt" 
    #:exists 'append)

请参阅:https://docs.racket-lang.org/reference/Filesystem.html?q=lines-file#%28def._%28%28lib._racket%2Ffile..rkt%29._display-lines-to-file%29%29

(require racket/file)
(display-lines-to-file   lst     path                
     [  #:separator separator                
        #:mode mode-flag                 
        #:exists exists-flag])      →       void?