package rrdformat import ( "encoding/xml" "strconv" ) //const XMLNS = "https://oss.oetiker.ch/rrdtool/rrdtool-dump.xml" func xmlStart(name string) xml.StartElement { return xml.StartElement{ Name: xml.Name{ Local: name, }, } } func (rrd RRD) MarshalXML(e *xml.Encoder, start xml.StartElement) error { if err := e.EncodeToken(xml.Comment(" Round Robin Database Dump ")); err != nil { return err } if err := e.EncodeToken(xml.CharData("\n")); err != nil { return err } if err := e.EncodeToken(start); err != nil { return err } // 1. Version if err := e.EncodeElement(rrd.Header.Version, xmlStart("version")); err != nil { return err } // 2. Step if err := e.EncodeElement(rrd.Header.PDPStep, xmlStart("step")); err != nil { return err } if err := e.EncodeToken(xml.CharData(" ")); err != nil { return err } if err := e.EncodeToken(xml.Comment(" Seconds ")); err != nil { return err } // 3. Last Update if err := e.EncodeElement(rrd.LastUpdated, xmlStart("lastupdate")); err != nil { return err } // blank line if err := e.EncodeToken(xml.CharData("\n")); err != nil { return err } // 3. Data Sources for _, ds := range rrd.DSDefs { if err := e.EncodeElement(ds, xmlStart("ds")); err != nil { return err } } // 4. Round Robin Archives for _, rra := range rrd.RRADefs { if err := e.EncodeElement(rra, xmlStart("rra")); err != nil { return err } } if err := e.EncodeToken(start.End()); err != nil { return err } return nil } func (t TimeWithUsec) MarshalXML(e *xml.Encoder, start xml.StartElement) error { if err := e.EncodeToken(start); err != nil { return err } if err := e.EncodeToken(xml.CharData(strconv.FormatInt(int64(t.Sec), 10))); err != nil { return err } if err := e.EncodeToken(start.End()); err != nil { return err } if err := e.EncodeToken(xml.CharData(" ")); err != nil { return err } if err := e.EncodeToken(xml.Comment(t.Time().Format(" 2006-01-02 15:04:05 MST "))); err != nil { return err } return nil } func (ds DSDef) MarshalXML(e *xml.Encoder, start xml.StartElement) error { if err := e.EncodeToken(start); err != nil { return err } if err := e.EncodeElement(" "+ds.DSName+" ", xmlStart("name")); err != nil { return err } if err := e.EncodeElement(" "+ds.DSType+" ", xmlStart("type")); err != nil { return err } switch ds.DSType { case DST_CDEF: var rpnps []rrdbinary.RPNToken for _, param := range ds.Params { rpnps = append(rpnps, param.AsRPNTokens()...) } strs := make([]string, len(rpnps)) for _, rpnp := range rpnps { switch Op(rpnp.Op) { case OP_NUMBER: strs = append(strs, fmt.Sprintf("%d", rpnp.Val)) case OP_VARIABLE: if rpnp.Val < 0 || rpnp.Val >= len(rrd.DSDefs) { return fmt.Errorf("out-of-bounds %s %d", Op(rpnp.Op), rpnp.Val) } strs = append(strs, rrd.DSDefs[int(rpnp.Val)].Name) case OP_PREV_OTHER: if rpnp.Val < 0 || rpnp.Val >= len(rrd.DSDefs) { return fmt.Errorf("out-of-bounds %s %d", Op(rpnp.Op), rpnp.Val) } strs = append(strs, fmt.Sprintf("PREV(%s)", rrd.DSDefs[int(rpnp.Val)].Name)) default: strs = append(strs, rpnp.Op.String()) } } if err := e.EncodeElement(strings.Join(strs, ","), xmlStart("cdef")); err != nil { return err } default: } if err := e.EncodeToken(start.End()); err != nil { return err } }