ooni-probe-cli/cmd/ooniprobe/internal/output/output.go
Arturo Filastò ac7d7dc8a3
Add support for tracking the is_uploaded status in the results table (#312)
* Add support for tracking the is_uploaded status in the results table

* Add unit tests for measurement upload status

This implements: https://github.com/ooni/probe/issues/1457

* Update cmd/ooniprobe/internal/database/actions.go

Co-authored-by: Simone Basso <bassosimone@gmail.com>
2021-04-30 17:08:16 +02:00

180 lines
5.7 KiB
Go

package output
import (
"bufio"
"fmt"
"os"
"time"
"github.com/apex/log"
"github.com/mitchellh/go-wordwrap"
"github.com/ooni/probe-cli/v3/cmd/ooniprobe/internal/database"
)
// MeasurementJSON prints the JSON of a measurement
func MeasurementJSON(j map[string]interface{}) {
log.WithFields(log.Fields{
"type": "measurement_json",
"measurement_json": j,
}).Info("Measurement JSON")
}
// Progress logs a progress type event
func Progress(key string, perc float64, eta float64, msg string) {
log.WithFields(log.Fields{
"type": "progress",
"key": key,
"percentage": perc,
"eta": eta,
}).Info(msg)
}
// MeasurementSummaryData contains summary information on the measurement
type MeasurementSummaryData struct {
TotalRuntime float64
TotalCount int64
AnomalyCount int64
DataUsageUp float64
DataUsageDown float64
ASN uint
NetworkName string
NetworkCountryCode string
StartTime time.Time
}
// MeasurementSummary emits the measurement summary
func MeasurementSummary(msmt MeasurementSummaryData) {
log.WithFields(log.Fields{
"type": "measurement_summary",
"total_runtime": msmt.TotalRuntime,
"total_count": msmt.TotalCount,
"anomaly_count": msmt.AnomalyCount,
"data_usage_down": msmt.DataUsageDown,
"data_usage_up": msmt.DataUsageUp,
"asn": msmt.ASN,
"network_country_code": msmt.NetworkCountryCode,
"network_name": msmt.NetworkName,
"start_time": msmt.StartTime,
}).Info("measurement summary")
}
// MeasurementItem logs a progress type event
func MeasurementItem(msmt database.MeasurementURLNetwork, isFirst bool, isLast bool) {
log.WithFields(log.Fields{
"type": "measurement_item",
"is_first": isFirst,
"is_last": isLast,
"id": msmt.Measurement.ID,
"test_name": msmt.TestName,
"test_group_name": msmt.Result.TestGroupName,
"start_time": msmt.Measurement.StartTime,
"test_keys": msmt.TestKeys,
"network_country_code": msmt.Network.CountryCode,
"network_name": msmt.Network.NetworkName,
"asn": msmt.Network.ASN,
"runtime": msmt.Measurement.Runtime,
"url": msmt.URL.URL.String,
"url_category_code": msmt.URL.CategoryCode.String,
"url_country_code": msmt.URL.CountryCode.String,
"is_anomaly": msmt.IsAnomaly.Bool,
"is_uploaded": msmt.Measurement.IsUploaded,
"is_upload_failed": msmt.IsUploadFailed,
"upload_failure_msg": msmt.UploadFailureMsg.String,
"is_failed": msmt.IsFailed,
"failure_msg": msmt.FailureMsg.String,
"is_done": msmt.Measurement.IsDone,
"report_file_path": msmt.ReportFilePath.String,
"measurement_file_path": msmt.MeasurementFilePath.String,
}).Info("measurement")
}
// ResultItemData is the metadata about a result
type ResultItemData struct {
ID int64
Name string
StartTime time.Time
TestKeys string
MeasurementCount uint64
MeasurementAnomalyCount uint64
Runtime float64
Country string
NetworkName string
ASN uint
Done bool
IsUploaded bool
DataUsageDown float64
DataUsageUp float64
Index int
TotalCount int
}
// ResultItem logs a progress type event
func ResultItem(result ResultItemData) {
log.WithFields(log.Fields{
"type": "result_item",
"id": result.ID,
"name": result.Name,
"start_time": result.StartTime,
"test_keys": result.TestKeys,
"measurement_count": result.MeasurementCount,
"measurement_anomaly_count": result.MeasurementAnomalyCount,
"network_country_code": result.Country,
"network_name": result.NetworkName,
"asn": result.ASN,
"runtime": result.Runtime,
"is_done": result.Done,
"is_uploaded": result.IsUploaded,
"data_usage_down": result.DataUsageDown,
"data_usage_up": result.DataUsageUp,
"index": result.Index,
"total_count": result.TotalCount,
}).Info("result item")
}
// ResultSummaryData contains the summary data of a result
type ResultSummaryData struct {
TotalTests int64
TotalDataUsageUp float64
TotalDataUsageDown float64
TotalNetworks int64
}
// ResultSummary emits the result summary
func ResultSummary(result ResultSummaryData) {
log.WithFields(log.Fields{
"type": "result_summary",
"total_tests": result.TotalTests,
"total_data_usage_up": result.TotalDataUsageUp,
"total_data_usage_down": result.TotalDataUsageDown,
"total_networks": result.TotalNetworks,
}).Info("result summary")
}
// SectionTitle is the title of a section
func SectionTitle(text string) {
log.WithFields(log.Fields{
"type": "section_title",
"title": text,
}).Info(text)
}
// Paragraph makes a word-wrapped paragraph out of text
func Paragraph(text string) {
const width = 80
fmt.Println(wordwrap.WrapString(text, width))
}
// Bullet is like paragraph but with a bullet point in front
func Bullet(text string) {
const width = 80
fmt.Printf("• %s\n", wordwrap.WrapString(text, width))
}
// PressAnyKeyToContinue blocks until the user presses any key
func PressAnyKeyToContinue(text string) error {
fmt.Print(text)
_, err := bufio.NewReader(os.Stdin).ReadBytes('\n')
return err
}