Skip to content

Commit

Permalink
cmd/scollector: Replace external AD collector with built in collector
Browse files Browse the repository at this point in the history
  • Loading branch information
gbrayut committed Jun 17, 2015
1 parent 1cc2fd6 commit d3dd2dc
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 1 deletion.
71 changes: 71 additions & 0 deletions cmd/scollector/collectors/activedirectory_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package collectors

import (
"strings"
"time"

"bosun.org/metadata"
"bosun.org/opentsdb"
)

func init() {
c_ad := &IntervalCollector{
F: c_activedirectory_windows,
Interval: time.Minute * 5,
}
c_ad.init = wmiInitNamespace(c_ad, func() interface{} { return &[]MSAD_ReplNeighbor{} }, "", &adQuery, rootMSAD)
collectors = append(collectors, c_ad)
}

var (
adQuery string
rootMSAD = "root\\MicrosoftActiveDirectory"
)

func c_activedirectory_windows() (opentsdb.MultiDataPoint, error) {
var dst []MSAD_ReplNeighbor
err := queryWmiNamespace(adQuery, &dst, rootMSAD)
if err != nil {
return nil, err
}
var md opentsdb.MultiDataPoint
for _, v := range dst {
lastSuccess, err := wmiParseCIMDatetime(v.TimeOfLastSyncSuccess)
if err != nil {
return nil, err
}
tags := opentsdb.TagSet{"source": strings.ToLower(v.SourceDsaCN), "context": activedirectory_context(v.NamingContextDN)}
sinceLastSuccess := time.Now().Sub(lastSuccess).Seconds()
Add(&md, "activedirectory.replication.sync_age", sinceLastSuccess, tags, metadata.Gauge, metadata.Second, descADReplicationSuccess)
Add(&md, "activedirectory.replication.consecutive_failures", v.NumConsecutiveSyncFailures, tags, metadata.Gauge, metadata.Count, descADReplicationFailures)
}
return md, nil
}

const (
descADReplicationSuccess = "The number of seconds since the last successful replication attempt for this context."
descADReplicationFailures = "The number of consecutive failed replication attempts for this context."
)

type MSAD_ReplNeighbor struct {
SourceDsaCN string
NamingContextDN string
TimeOfLastSyncSuccess string
NumConsecutiveSyncFailures uint32
}

func activedirectory_context(NamingContextDN string) string {
if strings.HasPrefix(NamingContextDN, "DC=DomainDnsZones,") {
return "DomainDNSZones"
}
if strings.HasPrefix(NamingContextDN, "DC=ForestDnsZones,") {
return "ForestDnsZones"
}
if strings.HasPrefix(NamingContextDN, "CN=Schema,CN=Configuration,") {
return "Schema"
}
if strings.HasPrefix(NamingContextDN, "CN=Configuration,") {
return "Configuration"
}
return "Domain"
}
30 changes: 29 additions & 1 deletion cmd/scollector/collectors/wmi_windows.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
package collectors

import "bosun.org/_third_party/github.com/StackExchange/wmi"
import (
"fmt"
"strings"
"time"

"bosun.org/_third_party/github.com/StackExchange/wmi"
)

var (
epochUTCTime = time.Unix(0, 0).UTC()
)

func queryWmi(query string, dst interface{}) error {
return queryWmiNamespace(query, dst, "")
Expand All @@ -27,3 +37,21 @@ func wmiInitNamespace(c *IntervalCollector, dst func() interface{}, where string
}
}
}

// wmiParseDatetime converts a string from the CIM_DATETIME format into UTC time.
// Example: "20150616101948.494497-360" = 2015-06-16 04:19:48.494497 +0000 UTC.
func wmiParseCIMDatetime(cimdatetime string) (time.Time, error) {
i := strings.IndexAny(cimdatetime, "+-")
if i < 0 {
return epochUTCTime, fmt.Errorf("Invalid CIM_DATETIME format, cannot find UTC offset.")
}
t, err := time.Parse("20060102150405", cimdatetime[0:i])
if err != nil {
return epochUTCTime, err
}
offset, err := time.ParseDuration(fmt.Sprintf("%vm", cimdatetime[i:]))
if err != nil {
return epochUTCTime, err
}
return t.Add(offset), nil
}

0 comments on commit d3dd2dc

Please sign in to comment.