This repository has been archived by the owner on Oct 6, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
/
appd.go
361 lines (286 loc) · 9.61 KB
/
appd.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
package appd
/*
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <appdynamics.h>
// global configuration
struct appd_config cfg;
void dump_config(struct appd_config *cfg) {
printf("app name %s\n", cfg->app_name);
printf("tier name %s\n", cfg->tier_name);
printf("node name %s\n", cfg->node_name);
printf("\n");
printf("controller host %s\n", cfg->controller.host);
printf("controller port %d\n", cfg->controller.port);
printf("controller account %s\n", cfg->controller.account);
printf("controller access key %s\n", cfg->controller.access_key);
printf("controller use ssl %c\n", cfg->controller.use_ssl);
printf("\n");
printf("init timeout ms %d\n", cfg->init_timeout_ms);
printf("\n");
printf("http proxy host %s\n", cfg->controller.http_proxy.host);
printf("http proxy port %d\n", cfg->controller.http_proxy.port);
printf("http proxy username %s\n", cfg->controller.http_proxy.username);
printf("http proxy password file %s\n", cfg->controller.http_proxy.password_file);
}
void printpair(char *name, char *value) {
printf("%s = %s\n", name, value);
}
uintptr_t bt_handle_to_int(appd_bt_handle bt_handle) {
return (uintptr_t)bt_handle;
}
appd_bt_handle bt_int_to_handle(uintptr_t bt) {
return (appd_bt_handle)bt;
}
uintptr_t exit_handle_to_int(appd_exitcall_handle exitcall_handle) {
return (uintptr_t)exitcall_handle;
}
appd_bt_handle exit_int_to_handle(uintptr_t exit) {
return (appd_exitcall_handle)exit;
}
*/
import "C"
import (
"log"
"unsafe"
"net/http"
"strconv"
)
/*
* Some constants from appdynamics.h
*/
const CORRELATION_HEADER_NAME = C.APPD_CORRELATION_HEADER_NAME
const BACKEND_HTTP = C.APPD_BACKEND_HTTP
const BACKEND_DB = C.APPD_BACKEND_DB
const BACKEND_CACHE = C.APPD_BACKEND_CACHE
const BACKEND_RABBITMQ = C.APPD_BACKEND_RABBITMQ
const BACKEND_WEBSERVICE = C.APPD_BACKEND_WEBSERVICE
const ERROR_LEVEL_NOTICE = C.APPD_LEVEL_NOTICE
const ERROR_LEVEL_WARNING = C.APPD_LEVEL_WARNING
const ERROR_LEVEL_ERROR = C.APPD_LEVEL_ERROR
const APPD_BT = "APPD_BT"
type ID_properties_map map[string]string
// do not free the C.CString as the config struct is only pointers
func Init(appName string, controllerKey string) {
log.Println("Init called")
appName_c := C.CString(appName)
controllerKey_c := C.CString(controllerKey)
C.appd_config_init(&C.cfg)
C.cfg.app_name = appName_c
C.cfg.controller.access_key = controllerKey_c
}
func SetTierName(name string) {
C.cfg.tier_name = C.CString(name)
}
func SetNodeName(name string) {
C.cfg.node_name = C.CString(name)
}
func SetControllerHost(host string) {
C.cfg.controller.host = C.CString(host)
}
func SetControllerPort(port int16) {
C.cfg.controller.port = C.ushort(port)
}
func SetControllerAccount(account string) {
C.cfg.controller.account = C.CString(account)
}
func SetControllerUseSSL(ssl byte) {
C.cfg.controller.use_ssl = C.char(ssl)
}
// Proxy
func SetControllerProxyHost(host string) {
C.cfg.controller.http_proxy.host = C.CString(host)
}
func SetControllerProxyPort(port int16) {
C.cfg.controller.http_proxy.port = C.ushort(port)
}
func SetControllerProxyUsername(username string) {
C.cfg.controller.http_proxy.username = C.CString(username)
}
func SetControllerProxyPasswordFile(password_file string) {
C.cfg.controller.http_proxy.password_file = C.CString(password_file)
}
// Agent
func SetAgentProxyControlPort(port int16) {
C.cfg.agent_proxy.tcp_control_port = C.ushort(port)
}
func SetAgentProxyRequestPort(port int16) {
C.cfg.agent_proxy.tcp_request_port = C.ushort(port)
}
func SetAgentProxyReportingPort(port int16) {
C.cfg.agent_proxy.tcp_reporting_port = C.ushort(port)
}
func SetAgentProxyCommDir(dir string) {
C.cfg.agent_proxy.ipc_comm_dir = C.CString(dir)
}
func SetInitTimeout(timeout int) {
C.cfg.init_timeout_ms = C.int(timeout)
}
func Sdk_init() int {
//C.dump_config(&C.cfg)
rc := C.appd_sdk_init(&C.cfg)
return int(rc)
}
func Sdk_term() {
C.appd_sdk_term()
}
/*
* BT
*/
func BT_begin(name string, correlation string) uint64 {
name_c := C.CString(name)
correlation_c := C.CString(correlation)
defer C.free(unsafe.Pointer(name_c))
defer C.free(unsafe.Pointer(correlation_c))
bt := C.appd_bt_begin(name_c, correlation_c)
return uint64(C.bt_handle_to_int(bt))
}
func BT_end(bt uint64) {
C.appd_bt_end(C.bt_int_to_handle(C.uintptr_t(bt)))
}
func BT_set_url(bt uint64, name string) {
name_c := C.CString(name)
defer C.free(unsafe.Pointer(name_c))
C.appd_bt_set_url(C.bt_int_to_handle(C.uintptr_t(bt)), name_c)
}
func BT_is_snapshotting(bt uint64) int {
result := C.appd_bt_is_snapshotting(C.bt_int_to_handle(C.uintptr_t(bt)))
return int(result)
}
func BT_add_user_data(bt uint64, key string, value string) {
key_c := C.CString(key)
value_c := C.CString(value)
defer C.free(unsafe.Pointer(key_c))
defer C.free(unsafe.Pointer(value_c))
C.appd_bt_add_user_data(C.bt_int_to_handle(C.uintptr_t(bt)), key_c, value_c)
}
func BT_add_error(bt uint64, level uint32, message string, mark_bt_as_error int) {
message_c := C.CString(message)
defer C.free(unsafe.Pointer(message_c))
C.appd_bt_add_error(C.bt_int_to_handle(C.uintptr_t(bt)), level, message_c, C.int(mark_bt_as_error))
}
func BT_store(bt uint64, guid string) {
guid_c := C.CString(guid)
defer C.free(unsafe.Pointer(guid_c))
C.appd_bt_store(C.bt_int_to_handle(C.uintptr_t(bt)), guid_c)
}
func BT_get(guid string) uint64 {
guid_c := C.CString(guid)
defer C.free(unsafe.Pointer(guid_c))
bt := C.appd_bt_get(guid_c)
return uint64(C.bt_handle_to_int(bt))
}
/*
* Backend
*/
func Backend_declare(betype string, name string) {
betype_c := C.CString(betype)
name_c := C.CString(name)
defer C.free(unsafe.Pointer(betype_c))
defer C.free(unsafe.Pointer(name_c))
log.Println("Backend decalre", betype, name)
C.appd_backend_declare(C.CString(betype), C.CString(name))
}
func Backend_set_identifying_property(name string, key string, value string) int {
name_c := C.CString(name)
key_c := C.CString(key)
value_c := C.CString(value)
defer C.free(unsafe.Pointer(name_c))
defer C.free(unsafe.Pointer(key_c))
defer C.free(unsafe.Pointer(value_c))
rc := C.appd_backend_set_identifying_property(C.CString(name), C.CString(key), C.CString(value))
return int(rc)
}
func Backend_set_identifying_properties(name string, props ID_properties_map) int {
var rc C.int
name_c := C.CString(name)
defer C.free(unsafe.Pointer(name_c))
for key, value := range props {
key_c := C.CString(key)
value_c := C.CString(value)
rc = C.appd_backend_set_identifying_property(name_c, key_c, value_c)
C.free(unsafe.Pointer(key_c))
C.free(unsafe.Pointer(value_c))
if(rc != 0) {
break
}
}
return int(rc)
}
func Backend_add(name string) int {
name_c := C.CString(name)
defer C.free(unsafe.Pointer(name_c))
rc := C.appd_backend_add(name_c)
return int(rc)
}
func Backend_prevent_agent_resolution(name string) int {
name_c := C.CString(name)
defer C.free(unsafe.Pointer(name_c))
rc := C.appd_backend_prevent_agent_resolution(name_c)
return int(rc)
}
/*
* Exit
*/
func Exitcall_begin(bt uint64, name string) uint64 {
name_c := C.CString(name)
defer C.free(unsafe.Pointer(name_c))
bt_h := C.bt_int_to_handle(C.uintptr_t(bt))
exit := C.appd_exitcall_begin(bt_h, name_c)
return uint64(C.exit_handle_to_int(exit))
}
func Exitcall_end(exit uint64) {
exit_h := C.exit_int_to_handle(C.uintptr_t(exit))
C.appd_exitcall_end(exit_h)
}
func Exitcall_set_details(exit uint64, details string) int {
details_c := C.CString(details)
defer C.free(unsafe.Pointer(details_c))
rc := C.appd_exitcall_set_details(C.exit_int_to_handle(C.uintptr_t(exit)), details_c)
return int(rc)
}
func Exitcall_add_error(exit uint64, error_level uint32, message string, mark_bt_as_error int) {
message_c := C.CString(message)
defer C.free(unsafe.Pointer(message_c))
C.appd_exitcall_add_error(C.exit_int_to_handle(C.uintptr_t(exit)), error_level, message_c, C.int(mark_bt_as_error))
}
func Exitcall_get_correlation_header(exit uint64) string {
header := C.appd_exitcall_get_correlation_header(C.exit_int_to_handle(C.uintptr_t(exit)))
return C.GoString(header)
}
func Exitcall_store(exit uint64, guid string) {
guid_c := C.CString(guid)
defer C.free(unsafe.Pointer(guid_c))
C.appd_exitcall_store(C.exit_int_to_handle(C.uintptr_t(exit)), guid_c)
}
func Exitcall_get(guid string) uint64 {
guid_c := C.CString(guid)
defer C.free(unsafe.Pointer(guid_c))
exit := C.appd_exitcall_get(guid_c)
return uint64(C.exit_handle_to_int(exit))
}
/*
* HTTP wrappers
*/
/*
* Wrappers for http handlers
* name is the name used for the BT
*/
func WrapHandle(name string, pattern string, handler http.Handler) (string, http.Handler) {
return pattern, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// get correlation id from header
appd_correlation := r.Header.Get(CORRELATION_HEADER_NAME)
bt := BT_begin(name, appd_correlation)
defer BT_end(bt)
BT_set_url(bt, r.URL.String())
r.Header.Add(APPD_BT, strconv.FormatUint(bt, 10))
handler.ServeHTTP(w, r)
})
}
func WrapHandleFunc(name string, pattern string, handler func(http.ResponseWriter, *http.Request)) (string, func(http.ResponseWriter, *http.Request)) {
p, h := WrapHandle(name, pattern, http.HandlerFunc(handler))
return p, func(w http.ResponseWriter, r *http.Request) {
h.ServeHTTP(w, r)
}
}