Почему Go's Logger не закрывает соединения с системным журналом?

У меня проблемы с сервисом, о котором я пишу. У меня есть запись в системный журнал следующим образом: http://technosophos.com/2013/09/14/using-gos-built-logger-log-syslog.html

но когда я убиваю службу через CTRL-C, что-то оставляет открытыми соединения с syslogd. Я все равно не вижу, чтобы начать очистку. Что мне не хватает

например syslog.Writer.Close() кажется мне недоступным, но я могу сказать, что очистки не происходит. Я вижу соединения, застрявшие в состоянии CLOSE_WAIT, и мой syslogd начинает зависать и отказываться от сотрудничества.

пример:

package main

import (
    "github.com/davecgh/go-spew/spew" // DEBUG
    "log"
    "log/syslog"
    "os"
    "os/signal"
    "syscall"
)

func main() {
    logWriter, err := syslog.New(syslog.LOG_NOTICE, "mybrokenprog")
    spew.Dump(logWriter) // DEBUG
    spew.Dump(err)       // DEBUG
    if err == nil {
        log.SetOutput(logWriter)
    }

    chansigs := make(chan os.Signal, 1)
    signal.Notify(chansigs, os.Interrupt, syscall.SIGTERM, syscall.SIGKILL)
    log.Print("writing to syslog. waiting for shutdown signal")
    for {
        sig := <-chansigs // we just wait here for a signal to shutdown
        log.Print("signal received...shutting down")
        logWriter.Close() // but this throws the panic excerpted below
        if sig == os.Interrupt {
            os.Exit(0)
        }
        os.Exit(1)
    }
}

РЕДАКТИРОВАТЬ: приведенный выше код устраняет проблему. см. комментарии. Перезагрузка для очистки застрявших подключений к системному журналу устранила проблему. Как только они там, они настойчивы. Даже инструкции OS X по перезапуску syslogd не помогли. РЕДАКТИРОВАТЬ: это была ошибка: паника: ошибка времени выполнения: неверный адрес памяти или разыменование нулевого указателя [сигнал 0xb code = 0x1 addr = 0x0 pc = 0xcb4fe]

горутина 1 [работает]: log/syslog.(*Writer).Close(0x0, 0x0, 0x0) /usr/local/Cellar/go/1.5.1/libexec/src/log/syslog/syslog.go:177 + 0x10e основной.главный(0x3)

Я не сомневаюсь, что делаю это неправильно. Просто новичок, который еще не видит, где.


person n8gard    schedule 30.10.2015    source источник
comment
Почему вы говорите, что syslog.Writer.Close() недоступен? Вы явно создаете syslog.Writer в ссылке, которую вы разместили.   -  person JimB    schedule 31.10.2015
comment
Я добавил некоторую информацию и пример кода. Спасибо!   -  person n8gard    schedule 31.10.2015
comment
Это не показывает, как вы справляетесь с очисткой. Похоже, что logWriter это nil, когда вы звоните Close().   -  person JimB    schedule 31.10.2015
comment
в порядке. Это интересно. думаю проблема именно в этом. как получить правильную ссылку на logWriter для вызова метода Close()? Что бы я сделал, приняв решение о очистке и выключении?   -  person n8gard    schedule 31.10.2015
comment
Вы должны показать нам, как вам удается не получить действительную ссылку на logWriter во время очистки. Все, что вы можете сделать во время очистки, это попытаться закрыть соединение.   -  person JimB    schedule 31.10.2015
comment
Ты прав, @JimB. Готово. Это в основном код с удаленными посторонними вещами. основной цикл прослушивает сигналы на выделенном канале, а затем вызывает .Close() на регистраторе - потому что я не знал, как это сделать. Я знаю, что это не работает. :)   -  person n8gard    schedule 01.11.2015
comment
Проверьте свою ошибку из syslog.New. Если есть ошибка, у вас нет logWriter для закрытия. Кроме того, вы фактически не выходите по сигналу.   -  person JimB    schedule 01.11.2015
comment
В порядке. Вы совершенно правы, в чем я никогда не сомневался, но теперь я получаю результаты, о которых вы говорите. Усугубляет проблему то, что мой syslogd был переведен в плохое состояние. Мне пришлось перезагрузить мой Mac, и теперь я получаю правильное поведение, которое вы описываете. Я обновил код выше. Я могу запускать это несколько раз, не оставляя застрявших подключений к системному журналу. Благодарю вас!   -  person n8gard    schedule 01.11.2015
comment
@ n8gard Хорошо, что тебе удалось решить свои проблемы. Не могли бы вы опубликовать ответ с исправлениями и принять его...   -  person user918176    schedule 19.11.2015


Ответы (1)


Проблема заключалась в изначальной структуре программы. Поток main() завершался раньше, чем горутина ведения журнала, и, таким образом, соединения были осиротевшими. После рефакторинга, чтобы предотвратить это, проблема исчезла.

person n8gard    schedule 22.01.2016