fix(logging): name the antenna disagreement, and confirm an outbound send
Two silences from one operator's log. The SteppIR is not blocked — it is being overruled. Every tune is commanded, acknowledged on the next poll with the frequency asked for, then replaced on the poll after by a different one: 21075 asked, 21075 confirmed, 21050 reported, again and again, with the operator tuning once more each time. Two minutes of that reads as a dead link. It now says what it is, once, when the motors have stopped and the reported frequency is more than 10 kHz from the commanded one — a controller quantising to its own grid is not a fault, one sitting somewhere else entirely is. UDP outbound had no positive signal at all: only failures were logged. When an operator sets up an ADIF message to a second logger and nothing arrives, "OpsLog never sent it" and "the other program did not take it" looked exactly the same from here — and the first is the common case, because a row created as an inbound ADIF listener instead of an outbound ADIF message matches nothing and emits nothing. Successful sends are logged with their destination and service, and a QSO logged with no outbound row says so once a session.
This commit is contained in:
@@ -86,12 +86,35 @@ func (m *Manager) EmitLoggedADIF(adif string) {
|
||||
if strings.TrimSpace(adif) == "" {
|
||||
return
|
||||
}
|
||||
for _, c := range m.Outbound(ServiceDBUpdated) {
|
||||
rows := m.Outbound(ServiceDBUpdated)
|
||||
if len(rows) == 0 {
|
||||
// Said once per session, not per QSO. An operator who configured a second
|
||||
// logger and sees nothing arrive needs to know the difference between "we
|
||||
// sent it" and "there was nothing to send to" — and the usual cause is a
|
||||
// row created as an inbound ADIF listener instead of an outbound message.
|
||||
m.noADIFOnce.Do(func() {
|
||||
applog.Printf("udp: a QSO was logged but no outbound \"ADIF message\" row is enabled — " +
|
||||
"nothing is forwarded to another logger")
|
||||
})
|
||||
return
|
||||
}
|
||||
for _, c := range rows {
|
||||
m.sendTo(c, []byte(adif))
|
||||
}
|
||||
}
|
||||
|
||||
// sendTo resolves the row's destination (host:port) and fires one datagram.
|
||||
//
|
||||
// A successful send is logged, not just a failure. UDP has no delivery report:
|
||||
// when an operator says "I set up an ADIF message to Logger32 on port 2250 and
|
||||
// nothing arrives", the only thing that separates "OpsLog never sent it" from
|
||||
// "the other program did not take it" is a line saying we sent. Without one,
|
||||
// both look identical from here — and the first is far more common, because a
|
||||
// row created as an INBOUND ADIF listener rather than an OUTBOUND ADIF message
|
||||
// matches nothing and emits nothing, in silence.
|
||||
//
|
||||
// Rate is not a concern: these fire on a QSO being logged or a frequency
|
||||
// change, not per packet on a socket.
|
||||
func (m *Manager) sendTo(c Config, payload []byte) {
|
||||
host := strings.TrimSpace(c.DestinationIP)
|
||||
if host == "" {
|
||||
@@ -100,5 +123,7 @@ func (m *Manager) sendTo(c Config, payload []byte) {
|
||||
dst := fmt.Sprintf("%s:%d", host, c.Port)
|
||||
if err := SendUDP(dst, payload); err != nil {
|
||||
applog.Printf("udp: [%s] outbound send to %s failed: %v", c.Name, dst, err)
|
||||
return
|
||||
}
|
||||
applog.Printf("udp: [%s] sent %d bytes to %s (%s)", c.Name, len(payload), dst, c.ServiceType)
|
||||
}
|
||||
|
||||
@@ -497,6 +497,10 @@ type Manager struct {
|
||||
repo *Repo
|
||||
out chan Event
|
||||
|
||||
// noADIFOnce keeps the "nothing to forward to" note to one line a session
|
||||
// rather than one per QSO logged.
|
||||
noADIFOnce sync.Once
|
||||
|
||||
mu sync.Mutex
|
||||
inbound map[int64]*Server
|
||||
outbound []Config
|
||||
|
||||
Reference in New Issue
Block a user