自定义节拍运行错误:持续时间“ ns”无效
im working on a custum beat that decodes a binary file to extract data and send it to elasticsearch , the complication goes normaly but when i run it, it gives me a running time error of an invalid duration "ns" here is my code:
package beater
import (
"fmt"
"io/ioutil"
"math"
"time"
//"log"
"strconv"
"strings"
"github.com/elastic/beats/libbeat/beat"
"github.com/elastic/beats/libbeat/common"
"github.com/elastic/beats/libbeat/logp"
"github.com/elastic/beats/libbeat/publisher"
"github.com/bob96/hc34/config"
)
type Hc34 struct {
done chan struct{}
config config.Config
client publisher.Client
siteKey string
fileKey string
callEndDateTime string
callStartDateTime string
callerPartyNumber string
calledPartyNumber string
incomingTrunkKey string
outgoingTrunkKey string
blockNumber string
blockDateTime string
headerFunction int
headerUser int
callerCategory int
callerOrigineIdentity string
complementaryIdentity string
calledDigits string
traficType int
serviceType int
supportService int
chargeDuration int
chargeMeters int
outgoingTrunk string
reserved string
operatorIdentity string
operatorServiceType string
block string
filekey string
lastIndexTime time.Time
}
// Creates beater
func New(b *beat.Beat, cfg *common.Config) (beat.Beater, error) {
config := config.DefaultConfig
if err := cfg.Unpack(&config); err != nil {
return nil, fmt.Errorf("Error reading config file: %v", err)
}
bt := &Hc34{
done: make(chan struct{}),
config: config,
}
return bt, nil
}
func (bt *Hc34) Run(b *beat.Beat) error {
logp.Info("hc34 is running! Hit CTRL-C to stop it.")
bt.client = b.Publisher.Connect()
ticker := time.NewTicker(bt.config.Period)
//counter := 1
for {
now := time.Now()
bt.hc34DataHolderfunc(bt.config.Path)
bt.lastIndexTime = now
logp.Info("Event sent")
select {
case <-bt.done:
return nil
case <-ticker.C:
}
/*event := common.MapStr{
"@timestamp": common.Time(time.Now()),
"type": b.Name,
"counter": counter,
}
bt.client.PublishEvent(event)
logp.Info("Event sent")
counter++*/
}
}
func (bt *Hc34) Stop() {
bt.client.Close()
close(bt.done)
}
//checking error
func check(e error) {
if e != nil {
panic(e)
}
}
func (bt *Hc34) hc34DataHolderfunc(dirfile string) {
//reading the binary file
data, err := ioutil.ReadFile(dirfile)
check(err)
//t := f.ModTime()
bt.hc34decoderfunc(string(data))
event := common.MapStr{
"@timestamp": common.Time(time.Now()),
/*"siteKey": siteKey,
"fileKey": fileKey,*/
//"callEndDateTime": bt.callEndDateTime,
//"callStartDateTime": bt.callStartDateTime,
"callerPartyNumber": bt.callerPartyNumber,
"calledPartyNumber": bt.calledPartyNumber,
//"incomingTrunkKey": bt.incomingTrunkKey,
//"outgoingTrunkKey": bt.outgoingTrunkKey,
"blockNumber": bt.blockNumber,
"blockDateTime": bt.blockDateTime,
"headerFunction": bt.headerFunction,
"headerUser": bt.headerUser,
"callerCategory": bt.callerCategory,
"callerOrigineIdentity": bt.callerOrigineIdentity,
"complementaryIdentity": bt.complementaryIdentity,
"calledDigits": bt.calledDigits,
"traficType": bt.traficType,
"serviceType": bt.serviceType,
"supportService": bt.supportService,
"chargeDuration": bt.chargeDuration,
"chargeMeters": bt.chargeMeters,
//"outgoingTrunk": bt.outgoingTrunk,
"reserved": bt.reserved,
"peratorIdentity": bt.operatorIdentity,
"operatorServiceType": bt.operatorServiceType,
}
bt.client.PublishEvent(event)
}
type hc34decoder struct{
block string
siteKey string
filekey string
}
func (bt *Hc34) hc34decoderfunc(block string){
// Get header (32 bytes) and content (1932 bytes) from block
header :=block[0:64]
content :=block[64:len(block)]
// Get block key and date time from header
blockKey :=header[4:10]
yearBlock :=header[10:12]
//BDTdecode, err := hex.DecodeString(header[10:12])
bt.blockDateTime =bt.getDate(bt.getDateBlockHeader(header[10:22]))
/*if err != nil {
log.Fatal(err)
}*/
// process content to extract CDRs
start := 0
totalCdr := len(content) / 84
for z := 0; z < totalCdr; z++ {
record := content[start:start + 84]
start = start + 84
// Extract data from single record
//CEDdecode, err :=hex.DecodeString(record[10:12])
a:= hex2decimal(record[54:56])
headerFunction:= hex2decimal(record[0:2])
headerUser:= hex2decimal(record[2:4])
callerCategory:= hex2decimal(record[4:6])
callEndDateTime :=bt.getDate(bt.getDateCall(record[6:16], yearBlock))
callerOrigineIdentity:= strings.Replace(string(record[16:26]),"F","",-1)
complementaryIdentity := strings.Replace(string(record[26:36]),"F","",-1)
calledDigits:= strings.Replace(string(record[36:54]),"F","",-1)
traficType:= hex2decimal(strings.Replace(string(a),"F","",-1))
serviceType := hex2decimal(record[56:58])
supportService :=hex2decimal(record[58:60])
duration :=hex2decimal(record[60:64])
meters:= hex2decimal(record[64:70])
//outgoingTrunk :=strings.Replace(string(record[70:74]),"F", "",-1)
bt.reserved = record[74:78]
bt.operatorIdentity = strings.Replace(string(record[78:82]),"F", "",-1)
bt.operatorServiceType =record[82:84]
bt.blockNumber=blockKey
bt.callerPartyNumber = bt.getFormattedMsisdnHc34Caller(complementaryIdentity, callerOrigineIdentity)
bt.calledPartyNumber = bt.getFormattedMsisdnHc34Called(calledDigits)
bt.callStartDateTime = bt.getStartDate(callEndDateTime, int(duration) )
/*if err !=nil{
log.Fatal(err)
}*/
bt.headerFunction=int(headerFunction)
bt.headerUser=int(headerUser)
bt.callerCategory=int(callerCategory)
bt.traficType=int(traficType)
bt.serviceType=int(serviceType)
bt.supportService=int(supportService)
bt.chargeMeters=int(meters)
bt.chargeDuration=int(duration)
func (bt *Hc34) getStartDate(endTime string, duration int) string{
layout := "2006-01-02T15:04:05.000Z"
t, err := time.Parse(layout, endTime)
if err!=nil{
panic(err)
}
return (t.Add(time.Duration(-duration) * time.Second)).String()
}
/**
* Get the date of the call.
* @param input the quanted date
* @param year the year
* @return the date of the call
*/
func (bt *Hc34) getDateCall(input string,year string) string{
quant:= hex2decimal(input[1:4])
hour := input[4:len(input)]
return "20" + year + bt.getQuantDate(quant) + "" + hour
}
/**
* Get date of block header.
* @param input the quanted date
* @return the date block header
*/
func(bt *Hc34) getDateBlockHeader(input string) string{
year := input[0:2]
quant:= hex2decimal(input[3:6])
hour := input[6:len(input)];
/*if err!=nil{
panic(err)
}*/
return "20" + year + bt.getQuantDate(quant) + "" + hour
}
/**
* format date.
* @param date the date
* @return the formatted date
*/
func(bt *Hc34) getDate(date string) string{
year := date[0:4]
month := date[4:6]
day := date[6:8]
hour := date[8:10]
minute := date[10:12]
second := date[12:14]
return year + "-" + month + "-" + day + " " + hour + ":" + minute + ":" + second;
}
/**
* Format quanted date.
* @param quant the quanted date
* @return the formatted date
*/
func(bt *Hc34) getQuantDate(quant int) string{
nanoDayOfYear:=string(quant*24*60*60*1000*1000*1000) + "ns"
durt,err:=time.ParseDuration(nanoDayOfYear)
t := time.Date(2009, time.January, 01, 00, 0, 0, 0, time.UTC)
t=t.Add(durt)
if err!=nil{
panic(err)
}
return string(t.Month())+""+string(t.Day())
}
func bin(i int, prefix bool) string {
i64 := int64(i)
if prefix {
return "0b" + strconv.FormatInt(i64, 2) // base 2 for binary
} else {
return strconv.FormatInt(i64, 2) // base 2 for binary
}
}
func bin2int(binStr string) int {
// base 2 for binary
result, _ := strconv.ParseInt(binStr, 2, 64)
return int(result)
}
func hex(i int, prefix bool) string {
i64 := int64(i)
if prefix {
return "0x" + strconv.FormatInt(i64, 16) // base 16 for hexadecimal
} else {
return strconv.FormatInt(i64, 16) // base 16 for hexadecimal
}
}
func hex2int(hexStr string) int {
// base 16 for hexadecimal
result, _ := strconv.ParseInt(hexStr, 16, 64)
return int(result)
}
func hex2decimal(hexStr string) int{
base16 := 16;
var val float64
for i:=0; i>len(hexStr);i++{
vala:=hex2int(string(base16))
valo:=hex2int(string(hexStr[len(hexStr)-i]))
val+=float64(valo)*math.Pow(float64(vala),float64(i))
}
return int(val)
}
and here its the error that i have :
panic: time: invalid duration ns
goroutine 1 [running]:
github.com/bob96/hc34/beater.(*Hc34).getQuantDate(0xc42012a8c0, 0x0, 0x0, 0x9)
/home/hp/src/github.com/bob96/hc34/beater/hc34.go:354 +0x2cf
github.com/bob96/hc34/beater.(*Hc34).getDateBlockHeader(0xc42012a8c0, 0xc4202d000a, 0xc, 0x0, 0x0)
/home/hp/src/github.com/bob96/hc34/beater/hc34.go:324 +0x73
github.com/bob96/hc34/beater.(*Hc34).hc34decoderfunc(0xc42012a8c0, 0xc4202d0000, 0x2d128)
/home/hp/src/github.com/bob96/hc34/beater/hc34.go:190 +0x77
github.com/bob96/hc34/beater.(*Hc34).hc34DataHolderfunc(0xc42012a8c0, 0xc420103140, 0x5e)
/home/hp/src/github.com/bob96/hc34/beater/hc34.go:141 +0xd3
github.com/bob96/hc34/beater.(*Hc34).Run(0xc42012a8c0, 0xc420142420, 0xc4201424c8, 0xb)
/home/hp/src/github.com/bob96/hc34/beater/hc34.go:105 +0x109
github.com/bob96/hc34/vendor/github.com/elastic/beats/libbeat/beat.(*Beat).launch(0xc420142420, 0x9a84c8, 0x0, 0x0)
/home/hp/src/github.com/bob96/hc34/vendor/github.com/elastic/beats/libbeat/beat/beat.go:211 +0x706
github.com/bob96/hc34/vendor/github.com/elastic/beats/libbeat/beat.Run(0x9855d5, 0x4, 0x0, 0x0, 0x9a84c8, 0xc4200001a0, 0xc4200001a0)
/home/hp/src/github.com/bob96/hc34/vendor/github.com/elastic/beats/libbeat/beat/beat.go:136 +0x65
main.main()
/home/hp/src/github.com/bob96/hc34/main.go:12 +0x54
what i thought in the first place is that the date functions don't get any string from the file, because we can't have a duration type "ns" but we need to have an integer before "ns" like so : "500ns".
sorry if i put out all the code i just didn't understand where exectly is my problem.
thanks for helping me!
This line looks problematic:
nanoDayOfYear:=string(quant*24*60*60*1000*1000*1000) + "ns"
Specifically, string(...)
doesn't do what you want. Presumably you want to convert that number to a base-10 string. Try this instead:
nanoDayOfYear:=strconv.FormatInt(quant*24*60*60*1000*1000*1000, 10) + "ns"