comparison pkg/imports/gm.go @ 5529:f95f268a83bd aggregate-gm-import-logging

WIP: Continued work on aggregating GM logs.
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Sun, 24 Oct 2021 20:16:41 +0200
parents 133dc5b3076a
children 3ccbb6162112
comparison
equal deleted inserted replaced
5528:133dc5b3076a 5529:f95f268a83bd
320 } 320 }
321 return fn, nil 321 return fn, nil
322 } 322 }
323 323
324 type gmLog struct { 324 type gmLog struct {
325 isrs *models.Isrs 325 gid string
326 unknown bool 326 unknown bool
327 assumedZPG bool 327 assumedZPG bool
328 ignoredMeasureCodes []nts.Measure_code_enum 328 ignoredMeasureCodes []string
329 rescaleErrors []string
329 assumedCM int 330 assumedCM int
330 missingValues []time.Time 331 missingValues []time.Time
331 badValue int 332 badValue int
332 newM int 333 newM int
333 newP int 334 newP int
334 } 335 }
335 336
336 type gmLogs []*gmLog 337 type gmLogs []*gmLog
337 338
339 func extend(haystack []string, needle string) []string {
340 for _, straw := range haystack {
341 if straw == needle {
342 return haystack
343 }
344 }
345 return append(haystack, needle)
346 }
347
348 func (gl *gmLog) addRescaleError(err error) {
349 gl.rescaleErrors = extend(gl.rescaleErrors, err.Error())
350 }
351
338 func (gl *gmLog) ignoreMeasureCode(mc nts.Measure_code_enum) { 352 func (gl *gmLog) ignoreMeasureCode(mc nts.Measure_code_enum) {
339 for _, m := range gl.ignoredMeasureCodes { 353 gl.ignoredMeasureCodes = extend(gl.ignoredMeasureCodes, string(mc))
340 if m == mc { 354 }
341 return 355
342 } 356 func (gls gmLogs) find(gid string) *gmLog {
343 } 357 for _, gl := range gls {
344 gl.ignoredMeasureCodes = append(gl.ignoredMeasureCodes, mc) 358 if gl.gid == gid {
359 return gl
360 }
361 }
362 return nil
345 } 363 }
346 364
347 func (gls gmLogs) logging(feedback Feedback) { 365 func (gls gmLogs) logging(feedback Feedback) {
348 gls.logUnknown(feedback) 366 gls.logUnknown(feedback)
349 gls.logAssumedZPG(feedback) 367 gls.logAssumedZPG(feedback)
350 // TODO: assumed CM 368 gls.logAssumedCM(feedback)
351 // TODO: bad values 369 // TODO: bad values
352 // TODO: missing values 370 // TODO: missing values
371 // TODO: rescale errors
353 // TODO: new predictions 372 // TODO: new predictions
354 // TODO: new measurements 373 // TODO: new measurements
374 }
375
376 func (gls gmLogs) logAssumedCM(feedback Feedback) {
377 var sb strings.Builder
378 for _, gl := range gls {
379 if gl.assumedCM > 0 {
380 if sb.Len() == 0 {
381 sb.WriteString("'Unit' not specified. Assuming 'cm': ")
382 } else {
383 sb.WriteString(", ")
384 }
385 fmt.Fprintf(&sb, "%s (%d)", gl.gid, gl.assumedCM)
386 }
387 }
388 if sb.Len() > 0 {
389 feedback.Warn(sb.String())
390 }
355 } 391 }
356 392
357 func (gls gmLogs) logUnknown(feedback Feedback) { 393 func (gls gmLogs) logUnknown(feedback Feedback) {
358 var sb strings.Builder 394 var sb strings.Builder
359 for _, gl := range gls { 395 for _, gl := range gls {
361 if sb.Len() == 0 { 397 if sb.Len() == 0 {
362 sb.WriteString("Cannot find following gauges: ") 398 sb.WriteString("Cannot find following gauges: ")
363 } else { 399 } else {
364 sb.WriteString(", ") 400 sb.WriteString(", ")
365 } 401 }
366 sb.WriteString(gl.isrs.String()) 402 sb.WriteString(gl.gid)
367 } 403 }
368 } 404 }
369 if sb.Len() > 0 { 405 if sb.Len() > 0 {
370 feedback.Warn(sb.String()) 406 feedback.Warn(sb.String())
371 } 407 }
378 if sb.Len() == 0 { 414 if sb.Len() == 0 {
379 sb.WriteString("'Reference_code' not specified. Assuming 'ZPG': ") 415 sb.WriteString("'Reference_code' not specified. Assuming 'ZPG': ")
380 } else { 416 } else {
381 sb.WriteString(", ") 417 sb.WriteString(", ")
382 } 418 }
383 sb.WriteString(gl.isrs.String()) 419 sb.WriteString(gl.gid)
384 } 420 }
385 } 421 }
386 if sb.Len() > 0 { 422 if sb.Len() > 0 {
387 feedback.Info(sb.String()) 423 feedback.Info(sb.String())
424 }
425 }
426
427 // logFinder is a helper to search recently used logs
428 // or create a new one if no log for a given gauge
429 // existed before.
430 func logFinder(logs *gmLogs) func(string) *gmLog {
431 var lastLog *gmLog
432 return func(gid string) *gmLog {
433 if lastLog != nil && lastLog.gid == gid {
434 return lastLog
435 }
436 if ll := logs.find(gid); ll != nil {
437 lastLog = ll
438 return ll
439 }
440 lastLog = &gmLog{gid: gid}
441 *logs = append(*logs, lastLog)
442 return lastLog
388 } 443 }
389 } 444 }
390 445
391 func doForGM( 446 func doForGM(
392 ctx context.Context, 447 ctx context.Context,
423 478
424 // To prevent spamming the log actual logging 479 // To prevent spamming the log actual logging
425 // is defered to be presented in an aggregated way. 480 // is defered to be presented in an aggregated way.
426 var logs gmLogs 481 var logs gmLogs
427 defer logs.logging(feedback) 482 defer logs.logging(feedback)
483
484 findLog := logFinder(&logs)
428 485
429 for _, msg := range result { 486 for _, msg := range result {
430 for _, wrm := range msg.Wrm { 487 for _, wrm := range msg.Wrm {
431 curr := string(*wrm.Geo_object.Id) 488 curr := string(*wrm.Geo_object.Id)
432 curr = strings.TrimSpace(curr) 489 curr = strings.TrimSpace(curr)
433 currIsrs, err := models.IsrsFromString(curr) 490 currIsrs, err := models.IsrsFromString(curr)
434 if err != nil { 491 if err != nil {
435 feedback.Warn("Invalid ISRS code %v", err) 492 feedback.Warn("Invalid ISRS code %v", err)
436 continue 493 continue
437 } 494 }
438 log := &gmLog{isrs: currIsrs} 495 log := findLog(curr)
439 logs = append(logs, log)
440 gids = append(gids, curr) 496 gids = append(gids, curr)
441 497
442 //feedback.Info("Found measurements/predictions for %s", curr) 498 //feedback.Info("Found measurements/predictions for %s", curr)
443 if !isKnown(curr) { 499 if !isKnown(curr) {
444 log.unknown = true 500 log.unknown = true
480 continue 536 continue
481 } 537 }
482 538
483 convert, err := rescale(unit) 539 convert, err := rescale(unit)
484 if err != nil { 540 if err != nil {
485 // TODO: log rescale error 541 log.addRescaleError(err)
486 feedback.Error(err.Error())
487 continue 542 continue
488 } 543 }
489 convert(measure.Value) 544 convert(measure.Value)
490 convert(measure.Value_min) 545 convert(measure.Value_min)
491 convert(measure.Value_max) 546 convert(measure.Value_max)