我正在研究一个自定义节拍,它解码一个二进制文件以提取数据并将其发送到 elasticsearch,复杂化正常但是当我运行它时,它给我一个无效持续时间“ns”的运行时间错误这是我的代码:
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)
}
这是我遇到的错误:
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
我首先想到的是日期函数不会从文件中获取任何字符串,因为我们不能有持续时间类型“ns”,但我们需要在“ns”之前有一个整数,就像这样:“500ns”。
抱歉,如果我把所有代码都放出来,我只是不明白我的问题到底在哪里。
谢谢你帮助我!
最佳答案
这一行看起来有问题:
nanoDayOfYear:=string(quant*24*60*60*1000*1000*1000) + "ns"
具体来说,string(...)
不会执行您想要的操作。大概您想将该数字转换为以 10 为基数的字符串。试试这个:
nanoDayOfYear:=strconv.FormatInt(quant*24*60*60*1000*1000*1000, 10) + "ns"
关于go - 自定义节拍运行错误: invalid duration "ns",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45500420/