-
Notifications
You must be signed in to change notification settings - Fork 5.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Teamspeak 3 input plugin (#3315)
- Loading branch information
1 parent
c569863
commit deed04c
Showing
6 changed files
with
237 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
# Teamspeak 3 Input Plugin | ||
|
||
This plugin uses the Teamspeak 3 ServerQuery interface of the Teamspeak server to collect statistics of one or more | ||
virtual servers. If you are querying an external Teamspeak server, make sure to add the host which is running Telegraf | ||
to query_ip_whitelist.txt in the Teamspeak Server directory. For information about how to configure the server take a look | ||
the [Teamspeak 3 ServerQuery Manual](http://media.teamspeak.com/ts3_literature/TeamSpeak%203%20Server%20Query%20Manual.pdf) | ||
|
||
### Configuration: | ||
|
||
``` | ||
# Reads metrics from a Teamspeak 3 Server via ServerQuery | ||
[[inputs.teamspeak]] | ||
## Server address for Teamspeak 3 ServerQuery | ||
# server = "127.0.0.1:10011" | ||
## Username for ServerQuery | ||
username = "serverqueryuser" | ||
## Password for ServerQuery | ||
password = "secret" | ||
## Array of virtual servers | ||
# virtual_servers = [1] | ||
``` | ||
|
||
### Measurements: | ||
|
||
- teamspeak | ||
- uptime | ||
- clients_online | ||
- total_ping | ||
- total_packet_loss | ||
- packets_sent_total | ||
- packets_received_total | ||
- bytes_sent_total | ||
- bytes_received_total | ||
|
||
### Tags: | ||
|
||
- The following tags are used: | ||
- virtual_server | ||
- name | ||
|
||
### Example output: | ||
|
||
``` | ||
teamspeak,virtual_server=1,name=LeopoldsServer,host=vm01 bytes_received_total=29638202639i,uptime=13567846i,total_ping=26.89,total_packet_loss=0,packets_sent_total=415821252i,packets_received_total=237069900i,bytes_sent_total=55309568252i,clients_online=11i 1507406561000000000 | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
package teamspeak | ||
|
||
import ( | ||
"github.com/multiplay/go-ts3" | ||
|
||
"github.com/influxdata/telegraf" | ||
"github.com/influxdata/telegraf/plugins/inputs" | ||
"strconv" | ||
) | ||
|
||
type Teamspeak struct { | ||
Server string | ||
Username string | ||
Password string | ||
VirtualServers []int `toml:"virtual_servers"` | ||
|
||
client *ts3.Client | ||
connected bool | ||
} | ||
|
||
func (ts *Teamspeak) Description() string { | ||
return "Reads metrics from a Teamspeak 3 Server via ServerQuery" | ||
} | ||
|
||
const sampleConfig = ` | ||
## Server address for Teamspeak 3 ServerQuery | ||
# server = "127.0.0.1:10011" | ||
## Username for ServerQuery | ||
username = "serverqueryuser" | ||
## Password for ServerQuery | ||
password = "secret" | ||
## Array of virtual servers | ||
# virtual_servers = [1] | ||
` | ||
|
||
func (ts *Teamspeak) SampleConfig() string { | ||
return sampleConfig | ||
} | ||
|
||
func (ts *Teamspeak) Gather(acc telegraf.Accumulator) error { | ||
var err error | ||
|
||
if !ts.connected { | ||
ts.client, err = ts3.NewClient(ts.Server) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
err = ts.client.Login(ts.Username, ts.Password) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
ts.connected = true | ||
} | ||
|
||
for _, vserver := range ts.VirtualServers { | ||
ts.client.Use(vserver) | ||
|
||
sm, err := ts.client.Server.Info() | ||
if err != nil { | ||
ts.connected = false | ||
return err | ||
} | ||
|
||
sc, err := ts.client.Server.ServerConnectionInfo() | ||
if err != nil { | ||
ts.connected = false | ||
return err | ||
} | ||
|
||
tags := map[string]string{ | ||
"virtual_server": strconv.Itoa(sm.ID), | ||
"name": sm.Name, | ||
} | ||
|
||
fields := map[string]interface{}{ | ||
"uptime": sm.Uptime, | ||
"clients_online": sm.ClientsOnline, | ||
"total_ping": sm.TotalPing, | ||
"total_packet_loss": sm.TotalPacketLossTotal, | ||
"packets_sent_total": sc.PacketsSentTotal, | ||
"packets_received_total": sc.PacketsReceivedTotal, | ||
"bytes_sent_total": sc.BytesSentTotal, | ||
"bytes_received_total": sc.BytesReceivedTotal, | ||
} | ||
|
||
acc.AddFields("teamspeak", fields, tags) | ||
} | ||
return nil | ||
} | ||
|
||
func init() { | ||
inputs.Add("teamspeak", func() telegraf.Input { | ||
return &Teamspeak{ | ||
Server: "127.0.0.1:10011", | ||
VirtualServers: []int{1}, | ||
} | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
package teamspeak | ||
|
||
import ( | ||
"bufio" | ||
"net" | ||
"strings" | ||
"testing" | ||
|
||
"github.com/influxdata/telegraf/testutil" | ||
) | ||
|
||
const welcome = `Welcome to the TeamSpeak 3 ServerQuery interface, type "help" for a list of commands and "help <command>" for information on a specific command.` | ||
const ok = `error id=0 msg=ok` | ||
const errorMsg = `error id=256 msg=command\snot\sfound` | ||
|
||
var cmd = map[string]string{ | ||
"login": "", | ||
"use": "", | ||
"serverinfo": `virtualserver_unique_identifier=a1vn9PLF8CMIU virtualserver_name=Testserver virtualserver_welcomemessage=Test virtualserver_platform=Linux virtualserver_version=3.0.13.8\s[Build:\s1500452811] virtualserver_maxclients=32 virtualserver_password virtualserver_clientsonline=2 virtualserver_channelsonline=1 virtualserver_created=1507400243 virtualserver_uptime=148 virtualserver_codec_encryption_mode=0 virtualserver_hostmessage virtualserver_hostmessage_mode=0 virtualserver_filebase=files\/virtualserver_1 virtualserver_default_server_group=8 virtualserver_default_channel_group=8 virtualserver_flag_password=0 virtualserver_default_channel_admin_group=5 virtualserver_max_download_total_bandwidth=18446744073709551615 virtualserver_max_upload_total_bandwidth=18446744073709551615 virtualserver_hostbanner_url virtualserver_hostbanner_gfx_url virtualserver_hostbanner_gfx_interval=0 virtualserver_complain_autoban_count=5 virtualserver_complain_autoban_time=1200 virtualserver_complain_remove_time=3600 virtualserver_min_clients_in_channel_before_forced_silence=100 virtualserver_priority_speaker_dimm_modificator=-18.0000 virtualserver_id=1 virtualserver_antiflood_points_tick_reduce=5 virtualserver_antiflood_points_needed_command_block=150 virtualserver_antiflood_points_needed_ip_block=250 virtualserver_client_connections=1 virtualserver_query_client_connections=1 virtualserver_hostbutton_tooltip virtualserver_hostbutton_url virtualserver_hostbutton_gfx_url virtualserver_queryclientsonline=1 virtualserver_download_quota=18446744073709551615 virtualserver_upload_quota=18446744073709551615 virtualserver_month_bytes_downloaded=0 virtualserver_month_bytes_uploaded=0 virtualserver_total_bytes_downloaded=0 virtualserver_total_bytes_uploaded=0 virtualserver_port=9987 virtualserver_autostart=1 virtualserver_machine_id virtualserver_needed_identity_security_level=8 virtualserver_log_client=0 virtualserver_log_query=0 virtualserver_log_channel=0 virtualserver_log_permissions=1 virtualserver_log_server=0 virtualserver_log_filetransfer=0 virtualserver_min_client_version=1445512488 virtualserver_name_phonetic virtualserver_icon_id=0 virtualserver_reserved_slots=0 virtualserver_total_packetloss_speech=0.0000 virtualserver_total_packetloss_keepalive=0.0000 virtualserver_total_packetloss_control=0.0000 virtualserver_total_packetloss_total=0.0000 virtualserver_total_ping=1.0000 virtualserver_ip=0.0.0.0,\s:: virtualserver_weblist_enabled=1 virtualserver_ask_for_privilegekey=0 virtualserver_hostbanner_mode=0 virtualserver_channel_temp_delete_delay_default=0 virtualserver_min_android_version=1407159763 virtualserver_min_ios_version=1407159763 virtualserver_status=online connection_filetransfer_bandwidth_sent=0 connection_filetransfer_bandwidth_received=0 connection_filetransfer_bytes_sent_total=0 connection_filetransfer_bytes_received_total=0 connection_packets_sent_speech=0 connection_bytes_sent_speech=0 connection_packets_received_speech=0 connection_bytes_received_speech=0 connection_packets_sent_keepalive=261 connection_bytes_sent_keepalive=10701 connection_packets_received_keepalive=261 connection_bytes_received_keepalive=10961 connection_packets_sent_control=54 connection_bytes_sent_control=15143 connection_packets_received_control=55 connection_bytes_received_control=4239 connection_packets_sent_total=315 connection_bytes_sent_total=25844 connection_packets_received_total=316 connection_bytes_received_total=15200 connection_bandwidth_sent_last_second_total=81 connection_bandwidth_sent_last_minute_total=141 connection_bandwidth_received_last_second_total=83 connection_bandwidth_received_last_minute_total=98`, | ||
"serverrequestconnectioninfo": `connection_filetransfer_bandwidth_sent=0 connection_filetransfer_bandwidth_received=0 connection_filetransfer_bytes_sent_total=0 connection_filetransfer_bytes_received_total=0 connection_packets_sent_total=369 connection_bytes_sent_total=28058 connection_packets_received_total=370 connection_bytes_received_total=17468 connection_bandwidth_sent_last_second_total=81 connection_bandwidth_sent_last_minute_total=109 connection_bandwidth_received_last_second_total=83 connection_bandwidth_received_last_minute_total=94 connection_connected_time=174 connection_packetloss_total=0.0000 connection_ping=1.0000`, | ||
} | ||
|
||
func TestGather(t *testing.T) { | ||
l, err := net.Listen("tcp", "127.0.0.1:0") | ||
if err != nil { | ||
t.Fatal("Initializing test server failed") | ||
} | ||
defer l.Close() | ||
|
||
go handleRequest(l, t) | ||
|
||
var acc testutil.Accumulator | ||
testConfig := Teamspeak{ | ||
Server: l.Addr().String(), | ||
Username: "serveradmin", | ||
Password: "test", | ||
VirtualServers: []int{1}, | ||
} | ||
err = testConfig.Gather(&acc) | ||
|
||
if err != nil { | ||
t.Fatalf("Gather returned error. Error: %s\n", err) | ||
} | ||
|
||
fields := map[string]interface{}{ | ||
"uptime": int(148), | ||
"clients_online": int(2), | ||
"total_ping": float32(1.0000), | ||
"total_packet_loss": float64(0.0000), | ||
"packets_sent_total": uint64(369), | ||
"packets_received_total": uint64(370), | ||
"bytes_sent_total": uint64(28058), | ||
"bytes_received_total": uint64(17468), | ||
} | ||
|
||
acc.AssertContainsFields(t, "teamspeak", fields) | ||
} | ||
|
||
func handleRequest(l net.Listener, t *testing.T) { | ||
c, err := l.Accept() | ||
if err != nil { | ||
t.Fatal("Error accepting test connection") | ||
} | ||
c.Write([]byte("TS3\n\r" + welcome + "\n\r")) | ||
for { | ||
msg, _, err := bufio.NewReader(c).ReadLine() | ||
if err != nil { | ||
return | ||
} | ||
r, exists := cmd[strings.Split(string(msg), " ")[0]] | ||
|
||
if exists { | ||
switch r { | ||
case "": | ||
c.Write([]byte(ok + "\n\r")) | ||
case "quit": | ||
c.Write([]byte(ok + "\n\r")) | ||
c.Close() | ||
return | ||
default: | ||
c.Write([]byte(r + "\n\r" + ok + "\n\r")) | ||
} | ||
} else { | ||
c.Write([]byte(errorMsg + "\n\r")) | ||
} | ||
} | ||
} |