From dffea12858a84f96f192c7e24db3646aa5bc2dbd Mon Sep 17 00:00:00 2001 From: Carlos Giraldo Date: Wed, 5 Dec 2018 13:23:47 +0100 Subject: [PATCH] weblogic 12.1.2 and 12.2 compatible --- README.md | 12 ++- _meta/beat.yml | 1 + _meta/fields.yml | 27 ++++++- beater/weblogic1212.go | 162 +++++++++++++++++++++++++++++++++++++ beater/weblogic122.go | 36 +++++---- beater/weblogicbeat.go | 35 ++++---- config/config.go | 2 + weblogicbeat.reference.yml | 5 +- weblogicbeat.yml | 20 ++--- 9 files changed, 254 insertions(+), 46 deletions(-) create mode 100644 beater/weblogic1212.go diff --git a/README.md b/README.md index c619c03..2db7e99 100644 --- a/README.md +++ b/README.md @@ -50,14 +50,16 @@ Sample configuration file weblogicbeat: period: 60s host: http://localhost:7001 + wlsversion : 12.2 username: weblogic password: welcome1 - servername: server1 + servernames: ["server1", "server2"] datasources: ["EssDS", "EDNDataSource"] applications: ["ESSAPP", "sample-app"] ``` - period: How often an event is sent to the output - host: Admin host and port +- wlsversion: Weblogic version. Suported versions 12.1.2 or 12.2 - username: Weblogic admin user - password: Weblogic admin password - datasources: Array of datasources to monitor @@ -95,6 +97,14 @@ mage setup *I had some issues on my mac with the make setup. I had to create manually a python2 env in build/python-env and install with pip the functools32 dependency. Be careful when using mage clean the build directory is erased and the python-env directory needs to be created again* +``` +cd build +rm -rf python-env +virtualenv python-env --python=python2.7 +source python-env/bin/activate +pip install functools32 +``` + ### Build diff --git a/_meta/beat.yml b/_meta/beat.yml index 5371175..2701c96 100644 --- a/_meta/beat.yml +++ b/_meta/beat.yml @@ -6,6 +6,7 @@ weblogicbeat: # Defines how often an event is sent to the output period: 60s host: http://localhost:7001 + wlsversion : 12.1.2 username: weblogic password: welcome1 servernames: ["server1"] diff --git a/_meta/fields.yml b/_meta/fields.yml index a1dc0ce..7600845 100644 --- a/_meta/fields.yml +++ b/_meta/fields.yml @@ -12,7 +12,22 @@ required: true description: > PLEASE UPDATE DOCUMENTATION - - name: metric_error + - name: err_server + type: string + required: false + description: > + PLEASE UPDATE DOCUMENTATION + - name: err_metric_type + type: string + required: false + description: > + PLEASE UPDATE DOCUMENTATION + - name: err_metric_error + type: string + required: false + description: > + PLEASE UPDATE DOCUMENTATION + - name: err_metric_body type: string required: false description: > @@ -62,6 +77,11 @@ required: false description: > PLEASE UPDATE DOCUMENTATION + - name: ds_server + type: string + required: false + description: > + PLEASE UPDATE DOCUMENTATION - name: ds_state type: string required: false @@ -102,6 +122,11 @@ required: false description: > PLEASE UPDATE DOCUMENTATION + - name: app_server + type: string + required: false + description: > + PLEASE UPDATE DOCUMENTATION - name: app_state type: string required: false diff --git a/beater/weblogic1212.go b/beater/weblogic1212.go new file mode 100644 index 0000000..5511720 --- /dev/null +++ b/beater/weblogic1212.go @@ -0,0 +1,162 @@ +package beater + +import ( + "fmt" + "time" + + gabs "github.com/Jeffail/gabs" + "github.com/elastic/beats/libbeat/beat" + "github.com/elastic/beats/libbeat/common" + "github.com/elastic/beats/libbeat/logp" + + "github.com/carlgira/weblogicbeat/config" + resty "gopkg.in/resty.v1" +) + +// Weblogicbeat configuration. +type Weblogic1212 struct { + bt Weblogicbeat + config config.Config +} + +func (wls *Weblogic1212) ServerStatusEvent() { + + for _, server_name := range wls.config.ServerNames { + resp_server_status, err_server_status := resty.R(). + SetHeader("Accept", "application/json"). + SetHeader("X-Requested-By", "weblogicbeat"). + SetBasicAuth(wls.config.Username, wls.config.Password). + Get(wls.config.Host + "/management/tenant-monitoring/servers/" + server_name) + + if resp_server_status.StatusCode() != 200 { + wls.SendErrorEvent(server_name, "server_status", fmt.Sprintf("%v", err_server_status), fmt.Sprintf("%v", resp_server_status)) + continue + } + + json_server_status, _ := gabs.ParseJSON([]byte(resp_server_status.String())) + server := json_server_status.Path("body.item").Data().(map[string]interface{}) + + server_status_event := beat.Event{ + Timestamp: time.Now(), + Fields: common.MapStr{ + "wb_server": server_name, + "wb_metric_type": "server_status", + "srv_name": server["name"], + "srv_state": server["state"], + "srv_heapFreeCurrent": int(server["heapFreeCurrent"].(float64) / 1000000), + "srv_heapSizeCurrent": int(server["heapSizeCurrent"].(float64) / 1000000), + "srv_heapSizeMax": int(server["heapSizeMax"].(float64) / 1000000), + "srv_health": server["health"], + }, + } + wls.bt.client.Publish(server_status_event) + logp.Info("Server status %s - event sent", server_name) + } +} + +func (wls *Weblogic1212) DatasourceStatusEvent() { + + for _, datasource := range wls.config.Datasources { + resp_ds, error_ds := resty.R(). + SetHeader("Accept", "application/json"). + SetHeader("X-Requested-By", "weblogicbeat"). + SetBasicAuth(wls.config.Username, wls.config.Password). + Get(wls.config.Host + "/management/tenant-monitoring/datasources/" + datasource) + + if resp_ds.StatusCode() != 200 { + wls.SendErrorEvent(datasource, "datasource_status", fmt.Sprintf("%v", error_ds), fmt.Sprintf("%v", resp_ds)) + continue + } + + json_ds_status, _ := gabs.ParseJSON([]byte(resp_ds.String())) + dsinfo, _ := json_ds_status.Path("body.item.instances").Children() + + for _, child := range dsinfo { + ds := child.Data().(map[string]interface{}) + + if !stringInSlice(ds["server"].(string), wls.config.ServerNames) { + continue + } + + datasource_status_event := beat.Event{ + Timestamp: time.Now(), + Fields: common.MapStr{ + "wb_server": ds["server"], + "wb_metric_type": "datasource_status", + "ds_server": ds["server"], + "ds_name": datasource, + "ds_state": ds["state"], + "ds_enabled": ds["enabled"], + "ds_activeConnectionsCurrentCount": ds["activeConnectionsCurrentCount"], + "ds_connectionsTotalCount": ds["connectionsTotalCount"], + "ds_activeConnectionsAverageCount": ds["activeConnectionsAverageCount"], + }, + } + wls.bt.client.Publish(datasource_status_event) + logp.Info("Datasource status %s - event sent", ds["server"]) + } + } + +} + +func (wls *Weblogic1212) ApplicationStatusEvent() { + + for _, application := range wls.config.Applications { + resp_app, err_app := resty.R(). + SetHeader("Accept", "application/json"). + SetHeader("X-Requested-By", "weblogicbeat"). + SetBasicAuth(wls.config.Username, wls.config.Password). + Get(wls.config.Host + "/management/tenant-monitoring/applications/" + application) + + if resp_app.StatusCode() != 200 { + wls.SendErrorEvent(application, "application_status", fmt.Sprintf("%v", err_app), fmt.Sprintf("%v", resp_app)) + continue + } + + json_application_status, _ := gabs.ParseJSON([]byte(resp_app.String())) + appinfo := json_application_status.Path("body.item").Data().(map[string]interface{}) + + for _, server_name := range wls.config.ServerNames { + application_status_event := beat.Event{ + Timestamp: time.Now(), + Fields: common.MapStr{ + "wb_server": server_name, + "wb_metric_type": "application_status", + "app_server": server_name, + "app_name": application, + "app_componentName": application, + "app_state": appinfo["state"], + "app_health": appinfo["health"], + }, + } + wls.bt.client.Publish(application_status_event) + logp.Info("Application status %s - event sent", server_name) + } + } +} + +func (wls *Weblogic1212) ThreadStatusEvent() { +} + +func (wls *Weblogic1212) SendErrorEvent(serverName string, metricType string, err string, body string) { + error_event := beat.Event{ + Timestamp: time.Now(), + Fields: common.MapStr{ + "err_server": serverName, + "err_metric_type": metricType, + "err_metric_error": err, + "err_metric_body": body, + }, + } + wls.bt.client.Publish(error_event) + logp.Info("Error : %s", err) +} + +func stringInSlice(a string, list []string) bool { + for _, b := range list { + if b == a { + return true + } + } + return false +} diff --git a/beater/weblogic122.go b/beater/weblogic122.go index 5587e10..096555e 100644 --- a/beater/weblogic122.go +++ b/beater/weblogic122.go @@ -28,8 +28,8 @@ func (wls *Weblogic122) ServerStatusEvent() { SetBasicAuth(wls.config.Username, wls.config.Password). Get(wls.config.Host + "/management/weblogic/latest/domainRuntime/serverRuntimes/" + server_name + "?links=none&fields=name,state,healthState") - if err_server_status != nil { - wls.SendErrorEvent(server_name, "server_status", fmt.Sprintf("%v", err_server_status)) + if resp_server_status.StatusCode() != 200 { + wls.SendErrorEvent(server_name, "server_status", fmt.Sprintf("%v", err_server_status), fmt.Sprintf("%v", resp_server_status)) continue } @@ -43,8 +43,8 @@ func (wls *Weblogic122) ServerStatusEvent() { SetBasicAuth(wls.config.Username, wls.config.Password). Get(wls.config.Host + "/management/weblogic/latest/domainRuntime/serverRuntimes/" + server_name + "/JVMRuntime?links=none&fields=heapSizeCurrent,heapFreeCurrent,heapFreePercent,heapSizeMax") - if err_server_jvm != nil { - wls.SendErrorEvent(server_name, "server_status", fmt.Sprintf("%v", err_server_jvm)) + if resp_server_jvm.StatusCode() != 200 { + wls.SendErrorEvent(server_name, "server_status", fmt.Sprintf("%v", err_server_jvm), fmt.Sprintf("%v", resp_server_jvm)) continue } @@ -80,8 +80,8 @@ func (wls *Weblogic122) DatasourceStatusEvent() { SetBasicAuth(wls.config.Username, wls.config.Password). Get(wls.config.Host + "/management/weblogic/latest/domainRuntime/serverRuntimes/" + server_name + "/JDBCServiceRuntime/JDBCDataSourceRuntimeMBeans/" + datasource + "?links=none&fields=activeConnectionsCurrentCount,activeConnectionsAverageCount,connectionsTotalCount,enabled,state,name") - if error_ds != nil { - wls.SendErrorEvent(server_name, "datasource_status", fmt.Sprintf("%v", error_ds)) + if resp_ds.StatusCode() != 200 { + wls.SendErrorEvent(server_name, "datasource_status", fmt.Sprintf("%v", error_ds), fmt.Sprintf("%v", resp_ds)) continue } @@ -105,6 +105,7 @@ func (wls *Weblogic122) DatasourceStatusEvent() { Fields: common.MapStr{ "wb_server": server_name, "wb_metric_type": "datasource_status", + "ds_server": server_name, "ds_name": datasource, "ds_state": dsinfo["state"], "ds_enabled": dsinfo["enabled"], @@ -130,8 +131,8 @@ func (wls *Weblogic122) ApplicationStatusEvent() { SetBasicAuth(wls.config.Username, wls.config.Password). Get(wls.config.Host + "/management/weblogic/latest/domainRuntime/serverRuntimes/" + server_name + "/applicationRuntimes/" + application + "?links=none&fields=name,healthState") - if err_app != nil { - wls.SendErrorEvent(server_name, "application_status", fmt.Sprintf("%v", err_app)) + if resp_app.StatusCode() != 200 { + wls.SendErrorEvent(server_name, "application_status", fmt.Sprintf("%v", err_app), fmt.Sprintf("%v", resp_app)) continue } @@ -145,8 +146,8 @@ func (wls *Weblogic122) ApplicationStatusEvent() { SetBasicAuth(wls.config.Username, wls.config.Password). Get(wls.config.Host + "/management/weblogic/latest/domainRuntime/serverRuntimes/" + server_name + "/applicationRuntimes/" + application + "/componentRuntimes?fields=openSessionsCurrentCount,sessionsOpenedTotalCount,openSessionsHighCount,applicationIdentifier,status,componentName&links=none") - if err_app_comp != nil { - wls.SendErrorEvent(server_name, "application_status", fmt.Sprintf("%v", err_app_comp)) + if resp_app_comp.StatusCode() != 200 { + wls.SendErrorEvent(server_name, "application_status", fmt.Sprintf("%v", err_app_comp), fmt.Sprintf("%v", resp_app_comp)) continue } @@ -161,6 +162,7 @@ func (wls *Weblogic122) ApplicationStatusEvent() { Fields: common.MapStr{ "wb_server": server_name, "wb_metric_type": "application_status", + "app_server": server_name, "app_name": application, "app_componentName": comp["componentName"], "app_state": comp["status"], @@ -186,8 +188,8 @@ func (wls *Weblogic122) ThreadStatusEvent() { SetBasicAuth(wls.config.Username, wls.config.Password). Get(wls.config.Host + "/management/weblogic/latest/domainRuntime/serverRuntimes/" + server_name + "/threadPoolRuntime?links=none&fields=overloadRejectedRequestsCount,pendingUserRequestCount,executeThreadTotalCount,healthState,stuckThreadCount,throughput,hoggingThreadCount") - if err_thread_status != nil { - wls.SendErrorEvent(server_name, "thread_status", fmt.Sprintf("%v", err_thread_status)) + if resp_thread_status.StatusCode() != 200 { + wls.SendErrorEvent(server_name, "thread_status", fmt.Sprintf("%v", err_thread_status), fmt.Sprintf("%v", resp_thread_status)) continue } @@ -200,6 +202,7 @@ func (wls *Weblogic122) ThreadStatusEvent() { Fields: common.MapStr{ "wb_server": server_name, "wb_metric_type": "thread_status", + "th_server": server_name, "th_overloadRejectedRequestsCount": threads["overloadRejectedRequestsCount"], "th_pendingUserRequestCount": threads["pendingUserRequestCount"], "th_executeThreadTotalCount": threads["executeThreadTotalCount"], @@ -215,13 +218,14 @@ func (wls *Weblogic122) ThreadStatusEvent() { } } -func (wls *Weblogic122) SendErrorEvent(serverName string, metricType string, err string) { +func (wls *Weblogic122) SendErrorEvent(serverName string, metricType string, err string, body string) { error_event := beat.Event{ Timestamp: time.Now(), Fields: common.MapStr{ - "server": serverName, - "metric_type": metricType, - "metric_error": err, + "err_server": serverName, + "err_metric_type": metricType, + "err_metric_error": err, + "err_metric_body": body, }, } wls.bt.client.Publish(error_event) diff --git a/beater/weblogicbeat.go b/beater/weblogicbeat.go index f702f96..202a531 100644 --- a/beater/weblogicbeat.go +++ b/beater/weblogicbeat.go @@ -57,23 +57,26 @@ func (bt *Weblogicbeat) Run(b *beat.Beat) error { case <-ticker.C: } - wls := &Weblogic122{ - bt: *bt, - config: bt.config, + if bt.config.WlsVersion == "12.1.2" { + wls := &Weblogic1212{ + bt: *bt, + config: bt.config, + } + wls.ServerStatusEvent() + wls.DatasourceStatusEvent() + wls.ApplicationStatusEvent() + wls.ThreadStatusEvent() + + } else { + wls := &Weblogic122{ + bt: *bt, + config: bt.config, + } + wls.ServerStatusEvent() + wls.DatasourceStatusEvent() + wls.ApplicationStatusEvent() + wls.ThreadStatusEvent() } - - // SERVERS STATUS - wls.ServerStatusEvent() - - // DATASOURCES STATUS - wls.DatasourceStatusEvent() - - // APPLICATIONS STATUS - wls.ApplicationStatusEvent() - - // THREAD STATUS - wls.ThreadStatusEvent() - counter++ } } diff --git a/config/config.go b/config/config.go index 3b57e76..7cdd5a0 100644 --- a/config/config.go +++ b/config/config.go @@ -8,6 +8,7 @@ import "time" type Config struct { Period time.Duration `config:"period"` Host string `config:"host"` + WlsVersion string `config:"wlsversion"` Username string `config:"username"` Password string `config:"password"` ServerNames []string `config:"servernames"` @@ -18,6 +19,7 @@ type Config struct { var DefaultConfig = Config{ Period: 1 * time.Second, Host: "", + WlsVersion: "12.2", Username: "", Password: "", ServerNames: []string{}, diff --git a/weblogicbeat.reference.yml b/weblogicbeat.reference.yml index 6fcc3d1..25e1650 100644 --- a/weblogicbeat.reference.yml +++ b/weblogicbeat.reference.yml @@ -6,6 +6,7 @@ weblogicbeat: # Defines how often an event is sent to the output period: 60s host: http://localhost:7001 + wlsversion : 12.1.2 username: weblogic password: welcome1 servernames: ["server1"] @@ -436,11 +437,11 @@ output.elasticsearch: # and retry until all events are published. Set max_retries to a value less # than 0 to retry until all events are published. The default is 3. #max_retries: 3 - + # The maximum number of events to bulk in a single Logstash request. The # default is 2048. #bulk_max_size: 2048 - + # The number of seconds to wait for responses from the Logstash server before # timing out. The default is 30s. #timeout: 30s diff --git a/weblogicbeat.yml b/weblogicbeat.yml index 6b407b3..85e52a9 100644 --- a/weblogicbeat.yml +++ b/weblogicbeat.yml @@ -4,13 +4,14 @@ weblogicbeat: # Defines how often an event is sent to the output - period: 2s - host: http://mktvppt04.os.amadeus.net:7121 + period: 60s + host: http://localhost:7001 + wlsversion : 12.1.2 username: weblogic - password: Manager3pt01 - servernames: ["vppt01"] - datasources: ["incaDatasource"] - applications: ["inca-ear"] + password: welcome1 + servernames: ["server1"] + datasources: ["EssDS", "EDNDataSource"] + applications: ["ESSAPP", "sample-app"] #================================ General ===================================== @@ -26,8 +27,7 @@ weblogicbeat: # output. #fields: # env: staging -output.console: - pretty: true + #============================== Dashboards ===================================== # These settings control loading the sample dashboards to the Kibana index. Loading @@ -71,9 +71,9 @@ setup.kibana: # Configure what output to use when sending the data collected by the beat. #-------------------------- Elasticsearch output ------------------------------ -#output.elasticsearch: +output.elasticsearch: # Array of hosts to connect to. -# hosts: ["localhost:9200"] + hosts: ["localhost:9200"] # Optional protocol and basic auth credentials. #protocol: "https"