Racket: file entry

I wrote a Racket program that needed to log information, but I wanted to store the logs in a file. My first attempt was to use "with-logging to-port" and use "open-output-file" to create the output port.

#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)

However, when I open the file after that, it is empty! Also, I cannot run this more than once, because "open-output-file" gives me an error that the file already exists.

+4
source share
4 answers

I am sure the reason is that you are not closing the file properly. This should work:

(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))

Instead of housekeeping, you can use call-with-output-file

(call-with-output-file "testing.txt"
  (λ (out) 
    (with-logging-to-port out
      (λ () (identity/log 4)) 'info))
  #:exists 'append)
+3
source

I give you the source of the log:

(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

Open the file with the 'append flag . For instance:

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

If the log information is in a list of lines, such as lst, you can also use the following function:

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

See: 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?
+1
source

Source: https://habr.com/ru/post/1652605/


All Articles