1/* -*- mode: systemtap; -*-
2 *
3 *     Copyright 2017 Couchbase, Inc.
4 *
5 *   Licensed under the Apache License, Version 2.0 (the "License");
6 *   you may not use this file except in compliance with the License.
7 *   You may obtain a copy of the License at
8 *
9 *       http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *   Unless required by applicable law or agreed to in writing, software
12 *   distributed under the License is distributed on an "AS IS" BASIS,
13 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *   See the License for the specific language governing permissions and
15 *   limitations under the License.
16 */
17
18/*
19 * SystemTap tapset to make it easier to trace libcouchbase
20 *
21 * All probes provided by libcouchbase can be listed using following command:
22 *
23 * stap -L 'process("${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/libcouchbase.so.${LCB_SONAME_FULL}").mark("*")'
24 */
25
26
27/**
28 * Convert opcode from couchbase KV protocol to string representation
29 */
30function libcouchbase_opcode:string(opcode:long)
31{
32    if (opcode == 0x00) return "GET"
33    else if (opcode == 0x01) return "SET"
34    else if (opcode == 0x02) return "ADD"
35    else if (opcode == 0x03) return "REPLACE"
36    else if (opcode == 0x04) return "DELETE"
37    else if (opcode == 0x05) return "INCREMENT"
38    else if (opcode == 0x06) return "DECREMENT"
39    else if (opcode == 0x08) return "FLUSH"
40    else if (opcode == 0x09) return "GETQ"
41    else if (opcode == 0x0a) return "NOOP"
42    else if (opcode == 0x0b) return "VERSION"
43    else if (opcode == 0x0e) return "APPEND"
44    else if (opcode == 0x0f) return "PREPEND"
45    else if (opcode == 0x10) return "STAT"
46    else if (opcode == 0x1b) return "VERBOSITY"
47    else if (opcode == 0x1c) return "TOUCH"
48    else if (opcode == 0x1d) return "GAT"
49    else if (opcode == 0x1f) return "HELLO"
50    else if (opcode == 0x20) return "SASL_LIST_MECHS"
51    else if (opcode == 0x21) return "SASL_AUTH"
52    else if (opcode == 0x22) return "SASL_STEP"
53    else if (opcode == 0x83) return "GET_REPLICA"
54    else if (opcode == 0x89) return "SELECT_BUCKET"
55    else if (opcode == 0x91) return "OBSERVE_SEQNO"
56    else if (opcode == 0x92) return "OBSERVE"
57    else if (opcode == 0x94) return "GET_LOCKED"
58    else if (opcode == 0x95) return "UNLOCK_KEY"
59    else if (opcode == 0xb5) return "GET_CLUSTER_CONFIG"
60    else if (opcode == 0xc5) return "SUBDOC_GET"
61    else if (opcode == 0xc6) return "SUBDOC_EXISTS"
62    else if (opcode == 0xc7) return "SUBDOC_DICT_ADD"
63    else if (opcode == 0xc8) return "SUBDOC_DICT_UPSERT"
64    else if (opcode == 0xc9) return "SUBDOC_DELETE"
65    else if (opcode == 0xca) return "SUBDOC_REPLACE"
66    else if (opcode == 0xcb) return "SUBDOC_ARRAY_PUSH_LAST"
67    else if (opcode == 0xcc) return "SUBDOC_ARRAY_PUSH_FIRST"
68    else if (opcode == 0xcd) return "SUBDOC_ARRAY_INSERT"
69    else if (opcode == 0xce) return "SUBDOC_ARRAY_ADD_UNIQUE"
70    else if (opcode == 0xcf) return "SUBDOC_COUNTER"
71    else if (opcode == 0xd0) return "SUBDOC_MULTI_LOOKUP"
72    else if (opcode == 0xd1) return "SUBDOC_MULTI_MUTATION"
73    else if (opcode == 0xd2) return "SUBDOC_GET_COUNT"
74    else if (opcode == 0xfe) return "GET_ERROR_MAP"
75    else return "UNKNOWN"
76}
77
78/**
79 * Convert HTTP request type to string representation
80 */
81function libcouchbase_http_type:string(type:long)
82{
83    if (type == 0) return "VIEW"
84    else if (type == 1) return "MANAGEMENT"
85    else if (type == 2) return "RAW"
86    else if (type == 3) return "N1QL"
87    else if (type == 4) return "FTS"
88    else if (type == 5) return "CBAS"
89    else return "UNKNOWN"
90}
91
92/**
93 * Convert HTTP request method to string representation
94 */
95function libcouchbase_http_method:string(method:long)
96{
97    if (method == 0) return "GET"
98    else if (method == 1) return "POST"
99    else if (method == 2) return "PUT"
100    else if (method == 3) return "DELETE"
101    else return "UNKNOWN"
102}
103
104/**
105 * probe libcouchbase.kv.get.begin - start of GET/GETL/GAT operation
106 *
107 * @lcb: client instance
108 * @opaque: unique number for this request (visible on network, returned by server back)
109 * @vbucket: number of partition
110 * @opcode: opcode, see memcached/protocol_binary.h
111 * @key: document id
112 * @expiration: document expiration (0 when should not expire)
113 *
114 * Example:
115 *
116 *   probe libcouchbase.kv.get.begin {
117 *     printf("[%p] opcode: %s, vbucket: %d, key: %s\n",
118 *         lcb, libcouchbase_opcode(opcode), vbucket, key)
119 *   }
120 *
121 *
122 *   $ stap  test.stp  -c "cbc get foo"
123 *   foo                  CAS=0x150268ca90610000, Flags=0x0, Size=13, Datatype=0x01(JSON)
124 *   {"foo":"bar"}
125 *   [0xf20d90] opcode: GET, vbucket: 115, key: foo
126 */
127probe libcouchbase.kv.get.begin =
128    process("${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/libcouchbase.so.${LCB_SONAME_FULL}").mark("get_begin")
129{
130    lcb = $arg1
131    opaque = $arg2
132    vbucket = $arg3
133    opcode = $arg4
134    key = user_string_n($arg5, $arg6)
135    expiration = $arg7
136}
137
138/**
139 * probe libcouchbase.kv.get.end - end of GET/GETL/GAT operation
140 *
141 * @lcb: client instance
142 * @opaque: unique number for this request (visible on network, returned by server back)
143 * @opcode: opcode, see memcached/protocol_binary.h
144 * @latency_ns: time from schedule to dispatch of the command
145 * @rc: return code from the library see libcouchbase/error.h
146 * @key: document id
147 * @bytes: document body
148 * @flags: document flags
149 * @cas: document CAS
150 * @datatype: document datatype, see memcached/protocol_binary.h
151 *
152 * Example:
153 *
154 *   probe libcouchbase.kv.get.end {
155 *     printf("[%p] opcode: %s, rc: %d, cas: 0x%x, key: %s, value: %s\n",
156 *         lcb, libcouchbase_opcode(opcode), rc, cas, key, bytes)
157 *   }
158 *
159 *
160 *   $ stap  test.stp  -c "cbc get foo"
161 *   foo                  CAS=0x150268ca90610000, Flags=0x0, Size=13, Datatype=0x01(JSON)
162 *   {"foo":"bar"}
163 *   [0x1b58dd0] opcode: GET, rc: 0, cas: 0x150268ca90610000, key: foo, value: {"foo":"bar"}
164 */
165probe libcouchbase.kv.get.end =
166    process("${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/libcouchbase.so.${LCB_SONAME_FULL}").mark("get_end")
167{
168    lcb = $arg1
169    opaque = $arg2
170    opcode = $arg3
171    latency_ns = $arg4
172    rc = $arg5
173    key = user_string_n($arg6, $arg7)
174    bytes = user_string_n($arg8, $arg9)
175    flags = $arg10
176    cas = $arg11
177    datatype = $arg12
178}
179
180/**
181 * probe libcouchbase.kv.arithmetic.begin - start of INCR/DECR operation
182 *
183 * @lcb: client instance
184 * @opaque: unique number for this request (visible on network, returned by server back)
185 * @vbucket: number of partition
186 * @opcode: opcode, see memcached/protocol_binary.h
187 * @key: document id
188 * @delta: the 64 bit value to change the counter
189 * @initial: the value to use, when document is not exist
190 * @expiration: document expiration (0 when should not expire)
191 *
192 * Example:
193 *
194 *   probe libcouchbase.kv.arithmetic.begin {
195 *     printf("[%p] opcode: %s, delta: %d, initial: %d, key: %s\n",
196 *         lcb, libcouchbase_opcode(opcode), delta, initial, key)
197 *   }
198 *
199 *
200 *   $ stap  test.stp  -c "cbc incr --initial 42 --delta 3 cnt"
201 *   cnt                 Current value is 42. CAS=0x15026eea18850000
202 *   [0x117bdd0] opcode: INCREMENT, delta: 3, initial: 42, key: cnt
203 */
204probe libcouchbase.kv.arithmetic.begin =
205    process("${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/libcouchbase.so.${LCB_SONAME_FULL}").mark("arithmetic_begin")
206{
207    lcb = $arg1
208    opaque = $arg2
209    vbucket = $arg3
210    opcode = $arg4
211    key = user_string_n($arg5, $arg6)
212    delta = $arg7
213    initial = $arg8
214    expiration = $arg9
215}
216
217/**
218 * probe libcouchbase.kv.arithmetic.end - end of INCR/DECR operation
219 *
220 * @lcb: client instance
221 * @opaque: unique number for this request (visible on network, returned by server back)
222 * @opcode: opcode, see memcached/protocol_binary.h
223 * @latency_ns: time from schedule to dispatch of the command
224 * @rc: return code from the library see libcouchbase/error.h
225 * @key: document id
226 * @value: current value of the counter (as 64bit number)
227 * @cas: document CAS
228 *
229 * Example:
230 *
231 *   probe libcouchbase.kv.arithmetic.end {
232 *     printf("[%p] opcode: %s, rc: %d, cas: 0x%x, key: %s, value: %d\n",
233 *         lcb, libcouchbase_opcode(opcode), rc, cas, key, value)
234 *   }
235 *
236 *
237 *   $ stap  test.stp  -c "cbc decr --delta 3 cnt"
238 *   cnt                 Current value is 42. CAS=0x15026f100ece0000
239 *   [0x6cf0b0] opcode: DECREMENT, rc: 0, cas: 0x15026f100ece0000, key: cnt, value: 42
240 */
241probe libcouchbase.kv.arithmetic.end =
242    process("${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/libcouchbase.so.${LCB_SONAME_FULL}").mark("arithmetic_end")
243{
244    lcb = $arg1
245    opaque = $arg2
246    opcode = $arg3
247    latency_ns = $arg4
248    rc = $arg5
249    key = user_string_n($arg6, $arg7)
250    value = $arg8
251    cas = $arg9
252}
253
254/**
255 * probe libcouchbase.kv.remove.begin - start of DELETE operation
256 *
257 * @lcb: client instance
258 * @opaque: unique number for this request (visible on network, returned by server back)
259 * @vbucket: number of partition
260 * @opcode: opcode, see memcached/protocol_binary.h
261 * @key: document id
262 *
263 * Example:
264 *
265 *   probe libcouchbase.kv.remove.begin {
266 *     printf("[%p] opcode: %s, key: %s\n",
267 *         lcb, libcouchbase_opcode(opcode), key)
268 *   }
269 *
270 *
271 *   $ stap  test.stp  -c "cbc rm cnt"
272 *   cnt                 Deleted. CAS=0x15026f2ec2c90000
273 *   [0x9280c0] opcode: DELETE, key: cnt
274 */
275probe libcouchbase.kv.remove.begin =
276    process("${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/libcouchbase.so.${LCB_SONAME_FULL}").mark("remove_begin")
277{
278    lcb = $arg1
279    opaque = $arg2
280    vbucket = $arg3
281    opcode = $arg4
282    key = user_string_n($arg5, $arg6)
283}
284
285/**
286 * probe libcouchbase.kv.remove.end - end of DELETE operation
287 *
288 * @lcb: client instance
289 * @opaque: unique number for this request (visible on network, returned by server back)
290 * @opcode: opcode, see memcached/protocol_binary.h
291 * @latency_ns: time from schedule to dispatch of the command
292 * @rc: return code from the library see libcouchbase/error.h
293 * @key: document id
294 * @cas: document CAS
295 *
296 * Example:
297 *
298 *   probe libcouchbase.kv.remove.end {
299 *     printf("[%p] opcode: %s, rc: %d, cas: 0x%x, key: %s\n",
300 *         lcb, libcouchbase_opcode(opcode), rc, cas, key)
301 *   }
302
303 *
304 *   $ stap  test.stp  -c "cbc rm cnt"
305 *   cnt                 Deleted. CAS=0x15026f2ec2c90000
306 *   [0x9280c0] opcode: DELETE, rc: 0, cas: 0x15026f2ec2c90000, key: cnt
307 */
308probe libcouchbase.kv.remove.end =
309    process("${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/libcouchbase.so.${LCB_SONAME_FULL}").mark("remove_end")
310{
311    lcb = $arg1
312    opaque = $arg2
313    opcode = $arg3
314    latency_ns = $arg4
315    rc = $arg5
316    key = user_string_n($arg6, $arg7)
317    cas = $arg8
318}
319
320/**
321 * probe libcouchbase.kv.store.begin - start of SET/ADD/REPLACE/APPEND/PREPEND operation
322 *
323 * @lcb: client instance
324 * @opaque: unique number for this request (visible on network, returned by server back)
325 * @vbucket: number of partition
326 * @opcode: opcode, see memcached/protocol_binary.h
327 * @key: document id
328 * @bytes: document body
329 * @flags: document flags
330 * @cas: document CAS
331 * @datatype: document datatype, see memcached/protocol_binary.h
332 * @expiration: document expiration (0 when should not expire)
333 *
334 * Example:
335 *
336 *   probe libcouchbase.kv.store.begin {
337 *     printf("[%p] opcode: %s, key: %s, value: %s, expiration: %d\n",
338 *         lcb, libcouchbase_opcode(opcode), key, bytes, expiration)
339 *   }
340 *
341 *
342 *   $ stap  test.stp  -c "cbc cp -e 30 foo"
343 *   foo                 Stored. CAS=0x15026f8450790000
344 *   [0x7e0070] opcode: SET, key: foo, value: {"foo":"bar"}, expiration: 30
345 */
346probe libcouchbase.kv.store.begin =
347    process("${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/libcouchbase.so.${LCB_SONAME_FULL}").mark("store_begin")
348{
349    lcb = $arg1
350    opaque = $arg2
351    vbucket = $arg3
352    opcode = $arg4
353    key = user_string_n($arg5, $arg6)
354    bytes = user_string_n($arg7, $arg8)
355    flags = $arg9
356    cas = $arg10
357    datatype = $arg11
358    expiration = $arg12
359}
360
361/**
362 * probe libcouchbase.kv.store.end - end of SET/ADD/REPLACE/APPEND/PREPEND operation
363 *
364 * @lcb: client instance
365 * @opaque: unique number for this request (visible on network, returned by server back)
366 * @opcode: opcode, see memcached/protocol_binary.h
367 * @latency_ns: time from schedule to dispatch of the command
368 * @rc: return code from the library see libcouchbase/error.h
369 * @key: document id
370 * @cas: document CAS
371 *
372 * Example:
373 *
374 *   probe libcouchbase.kv.store.end {
375 *     printf("[%p] opcode: %s, rc: %d, cas: 0x%x, key: %s\n",
376 *         lcb, libcouchbase_opcode(opcode), rc, cas, key)
377 *   }
378 *
379 *
380 *   $ stap  test.stp  -c "cbc cp -e 30 foo"
381 *   foo                 Stored. CAS=0x15026f8450790000
382 *   [0x7e0070] opcode: SET, rc: 0, cas: 0x15026f8450790000, key: foo
383 */
384probe libcouchbase.kv.store.end =
385    process("${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/libcouchbase.so.${LCB_SONAME_FULL}").mark("store_end")
386{
387    lcb = $arg1
388    opaque = $arg2
389    opcode = $arg3
390    latency_ns = $arg4
391    rc = $arg5
392    key = user_string_n($arg6, $arg7)
393    cas = $arg8
394}
395
396/**
397 * probe libcouchbase.kv.unlock.begin - start of UNLOCK operation
398 *
399 * @lcb: client instance
400 * @opaque: unique number for this request (visible on network, returned by server back)
401 * @vbucket: number of partition
402 * @opcode: opcode, see memcached/protocol_binary.h
403 * @key: document id
404 *
405 * Example:
406 *
407 *   probe libcouchbase.kv.unlock.begin {
408 *     printf("[%p] opcode: %s, key: %s\n",
409 *         lcb, libcouchbase_opcode(opcode), key)
410 *   }
411 *
412 *
413 *   $ stap  test.stp  -c "cbc unlock foo 0x15028f7bafc20000"
414 *   foo                  Unlocked
415 *   [0x20d7100] opcode: UNLOCK_KEY, key: foo
416 */
417probe libcouchbase.kv.unlock.begin =
418    process("${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/libcouchbase.so.${LCB_SONAME_FULL}").mark("unlock_begin")
419{
420    lcb = $arg1
421    opaque = $arg2
422    vbucket = $arg3
423    opcode = $arg4
424    key = user_string_n($arg5, $arg6)
425}
426
427/**
428 * probe libcouchbase.kv.unlock.end - end of UNLOCK operation
429 *
430 * @lcb: client instance
431 * @opaque: unique number for this request (visible on network, returned by server back)
432 * @opcode: opcode, see memcached/protocol_binary.h
433 * @latency_ns: time from schedule to dispatch of the command
434 * @rc: return code from the library see libcouchbase/error.h
435 * @key: document id
436 *
437 * Example:
438 *
439 *   probe libcouchbase.kv.unlock.end {
440 *     printf("[%p] opcode: %s, rc: %d, key: %s\n",
441 *         lcb, libcouchbase_opcode(opcode), rc, key)
442 *   }
443 *
444 *
445 *   $ stap  test.stp  -c "cbc unlock foo 0x15028f7bafc20000"
446 *   foo                  Unlocked
447 *   [0x20d7100] opcode: UNLOCK_KEY, rc: 0, key: foo
448 */
449probe libcouchbase.kv.unlock.end =
450    process("${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/libcouchbase.so.${LCB_SONAME_FULL}").mark("unlock_end")
451{
452    lcb = $arg1
453    opaque = $arg2
454    opcode = $arg3
455    latency_ns = $arg4
456    rc = $arg5
457    key = user_string_n($arg6, $arg7)
458}
459
460/**
461 * probe libcouchbase.kv.touch.begin - start of TOUCH operation
462 *
463 * @lcb: client instance
464 * @opaque: unique number for this request (visible on network, returned by server back)
465 * @vbucket: number of partition
466 * @opcode: opcode, see memcached/protocol_binary.h
467 * @key: document id
468 * @expiration: document expiration (0 when should not expire)
469 *
470 * Example:
471 *
472 *   probe libcouchbase.kv.touch.begin {
473 *     printf("[%p] opcode: %s, key: %s, expiration: %d\n",
474 *         lcb, libcouchbase_opcode(opcode), key, expiration)
475 *   }
476 *
477 *
478 *   $ stap  test.stp  -c "cbc touch -e 10 foo"
479 *   foo                 Touched. CAS=0x150290b309ad0000
480 *   [0x141edb0] opcode: TOUCH, rc: 0, cas: 0x150290b309ad0000, key: foo
481 */
482probe libcouchbase.kv.touch.begin =
483    process("${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/libcouchbase.so.${LCB_SONAME_FULL}").mark("touch_begin")
484{
485    lcb = $arg1
486    opaque = $arg2
487    vbucket = $arg3
488    opcode = $arg4
489    key = user_string_n($arg5, $arg6)
490    expiration = $arg7
491}
492
493/**
494 * probe libcouchbase.kv.touch.end - end of TOUCH operation
495 *
496 * @lcb: client instance
497 * @opaque: unique number for this request (visible on network, returned by server back)
498 * @opcode: opcode, see memcached/protocol_binary.h
499 * @latency_ns: time from schedule to dispatch of the command
500 * @rc: return code from the library see libcouchbase/error.h
501 * @key: document id
502 * @cas: document CAS
503 *
504 * Example:
505 *
506 *   probe libcouchbase.kv.touch.end {
507 *     printf("[%p] opcode: %s, rc: %d, cas: 0x%x, key: %s\n",
508 *         lcb, libcouchbase_opcode(opcode), rc, cas, key)
509 *   }
510 *
511 *
512 *   $ stap  test.stp  -c "cbc touch -e 10 foo"
513 *   foo                 Touched. CAS=0x150290b309ad0000
514 *   [0x141edb0] opcode: TOUCH, rc: 0, cas: 0x150290b309ad0000, key: foo
515 */
516probe libcouchbase.kv.touch.end =
517    process("${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/libcouchbase.so.${LCB_SONAME_FULL}").mark("touch_end")
518{
519    lcb = $arg1
520    opaque = $arg2
521    opcode = $arg3
522    latency_ns = $arg4
523    rc = $arg5
524    key = user_string_n($arg6, $arg7)
525    cas = $arg8
526}
527
528/*
529 * probe libcouchbase.kv.observe.begin - start of OBSERVE operation
530 *
531 * @lcb: client instance
532 * @opaque: unique number for this request (visible on network, returned by server back)
533 * @opcode: opcode, see memcached/protocol_binary.h
534 * @bytes: pointer to payload (as long)
535 * @nbytes: size of payload
536 *
537 * libcouchbase.observe.begin probe intended to be parsed in the handler.
538 * the bytes argument is a blob with nbytes length:
539 *
540 * +---------+---------+------------+----
541 * | 16 bits | 16 bits | nkey bytes | ...
542 * +---------+---------+------------+----
543 * | vbucket |   nkey  |    key     | ...
544 * +---------+---------+------------+----
545 *
546 * Example:
547 *
548 *   probe libcouchbase.kv.observe.begin {
549 *     printf("[%p] opcode: %d, opaque: %d\n", lcb, libcouchbase_opcode(opcode), opaque)
550 *     while (nbytes > 0) {
551 *       vbucket = ntohs(user_uint16(bytes))
552 *       nbytes -= 2
553 *       bytes += 2
554 *       nkey = ntohs(user_uint16(bytes))
555 *       nbytes -= 2
556 *       bytes += 2
557 *       key = user_string_n(bytes, nkey)
558 *       nbytes -= nkey
559 *       bytes += nkey
560 *       printf("    vbucket: %d, nkey: %d, key: %s\n", vbucket, nkey, key)
561 *     }
562 *   }
563 *
564 *
565 * The following command executed on cluster with 4 nodes, and replication factor 3.
566 *
567 *   $ stap  test.stp  -c "cbc observe foo bar"
568 *   foo                  [Replica] Status=0x1, CAS=0x1502952004ed0000
569 *   bar                  [Replica] Status=0x1, CAS=0x1502951fe0040000
570 *   foo                  [Replica] Status=0x1, CAS=0x1502952004ed0000
571 *   bar                  [Master] Status=0x1, CAS=0x1502951fe0040000
572 *   foo                  [Replica] Status=0x1, CAS=0x1502952004ed0000
573 *   bar                  [Replica] Status=0x1, CAS=0x1502951fe0040000
574 *   foo                  [Master] Status=0x1, CAS=0x1502952004ed0000
575 *   bar                  [Replica] Status=0x1, CAS=0x1502951fe0040000
576 *   [0xb33dc0] opcode: OBSERVE, opaque: 0
577 *      vbucket: 115, nkey: 3, key: foo
578 *      vbucket: 767, nkey: 3, key: bar
579 *   [0xb33dc0] opcode: OBSERVE, opaque: 1
580 *      vbucket: 115, nkey: 3, key: foo
581 *      vbucket: 767, nkey: 3, key: bar
582 *   [0xb33dc0] opcode: OBSERVE, opaque: 2
583 *      vbucket: 115, nkey: 3, key: foo
584 *      vbucket: 767, nkey: 3, key: bar
585 *   [0xb33dc0] opcode: OBSERVE, opaque: 3
586 *      vbucket: 115, nkey: 3, key: foo
587 *      vbucket: 767, nkey: 3, key: bar
588 */
589probe libcouchbase.kv.observe.begin =
590    process("${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/libcouchbase.so.${LCB_SONAME_FULL}").mark("observe_begin")
591{
592    lcb = $arg1
593    opaque = $arg2
594    opcode = $arg4
595    bytes = $arg5
596    nbytes = $arg6
597}
598
599/**
600 * probe libcouchbase.kv.observe.progress - intermediate response of OBSERVE operation
601 *
602 * @lcb: client instance
603 * @opaque: unique number for this request (visible on network, returned by server back)
604 * @vbucket: number of partition
605 * @opcode: opcode, see memcached/protocol_binary.h
606 * @latency_ns: time from schedule to dispatch of the command
607 * @rc: return code from the library see libcouchbase/error.h
608 * @key: document id
609 * @status: observe status: FOUND = 0x00, PERSISTED = 0x01, NOT_FOUND = 0x80
610 * @master: whether response from master node (zero if from replica)
611 * @ttp: time to persist
612 * @ttr: time to replicate
613 *
614 * Example:
615 *
616 *   probe libcouchbase.kv.observe.progress {
617 *     printf("[%p] opcode: %s, opaque: %d, rc: %d, key: %s, status: %d, master: %s\n",
618 *         lcb, libcouchbase_opcode(opcode), opaque, rc, key, status, master ? "true" : "false")
619 *   }
620 *
621 *
622 * The following command executed on cluster with 4 nodes, and replication factor 3.
623 *
624 *   $ stap  test.stp  -c "cbc observe foo bar"
625 *   foo                  [Replica] Status=0x1, CAS=0x1502952004ed0000
626 *   bar                  [Replica] Status=0x1, CAS=0x1502951fe0040000
627 *   foo                  [Replica] Status=0x1, CAS=0x1502952004ed0000
628 *   bar                  [Master] Status=0x1, CAS=0x1502951fe0040000
629 *   foo                  [Replica] Status=0x1, CAS=0x1502952004ed0000
630 *   bar                  [Replica] Status=0x1, CAS=0x1502951fe0040000
631 *   foo                  [Master] Status=0x1, CAS=0x1502952004ed0000
632 *   bar                  [Replica] Status=0x1, CAS=0x1502951fe0040000
633 *   [0xb33dc0] opcode: OBSERVE, opaque: 0, rc: 0, key: foo, status: 1, master: false
634 *   [0xb33dc0] opcode: OBSERVE, opaque: 0, rc: 0, key: bar, status: 1, master: false
635 *   [0xb33dc0] opcode: OBSERVE, opaque: 3, rc: 0, key: foo, status: 1, master: false
636 *   [0xb33dc0] opcode: OBSERVE, opaque: 3, rc: 0, key: bar, status: 1, master: true
637 *   [0xb33dc0] opcode: OBSERVE, opaque: 1, rc: 0, key: foo, status: 1, master: false
638 *   [0xb33dc0] opcode: OBSERVE, opaque: 1, rc: 0, key: bar, status: 1, master: false
639 *   [0xb33dc0] opcode: OBSERVE, opaque: 2, rc: 0, key: foo, status: 1, master: true
640 *   [0xb33dc0] opcode: OBSERVE, opaque: 2, rc: 0, key: bar, status: 1, master: false
641 */
642probe libcouchbase.kv.observe.progress =
643    process("${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/libcouchbase.so.${LCB_SONAME_FULL}").mark("observe_progress")
644{
645    lcb = $arg1
646    opaque = $arg2
647    opcode = $arg3
648    latency_ns = $arg4
649    rc = $arg5
650    key = user_string_n($arg6, $arg7)
651    cas = $arg8
652    status = $arg9
653    master = $arg10
654    ttp = $arg11
655    ttr = $arg12
656}
657
658/**
659 * probe libcouchbase.kv.observe.end - end of OBSERVE operation
660 *
661 * @lcb: client instance
662 * @opaque: unique number for this request (visible on network, returned by server back)
663 * @opcode: opcode, see memcached/protocol_binary.h
664 * @latency_ns: time from schedule to dispatch of the command
665 * @rc: return code from the library see libcouchbase/error.h
666 *
667 * Example:
668 *
669 *   probe libcouchbase.kv.observe.end {
670 *     printf("[%p] opcode: %s, opaque, rc: %d\n",
671 *         lcb, libcouchbase_opcode(opcode), opaque, rc)
672 *   }
673 *
674 *
675 * The following command executed on cluster with 4 nodes, and replication factor 3.
676 *
677 *   $ stap  test.stp  -c "cbc observe foo bar"
678 *   foo                  [Replica] Status=0x1, CAS=0x1502952004ed0000
679 *   bar                  [Replica] Status=0x1, CAS=0x1502951fe0040000
680 *   foo                  [Replica] Status=0x1, CAS=0x1502952004ed0000
681 *   bar                  [Master] Status=0x1, CAS=0x1502951fe0040000
682 *   foo                  [Replica] Status=0x1, CAS=0x1502952004ed0000
683 *   bar                  [Replica] Status=0x1, CAS=0x1502951fe0040000
684 *   foo                  [Master] Status=0x1, CAS=0x1502952004ed0000
685 *   bar                  [Replica] Status=0x1, CAS=0x1502951fe0040000
686 *   [0xb33dc0] opcode: OBSERVE, opaque: 0, rc: 0
687 *   [0xb33dc0] opcode: OBSERVE, opaque: 3, rc: 0
688 *   [0xb33dc0] opcode: OBSERVE, opaque: 1, rc: 0
689 *   [0xb33dc0] opcode: OBSERVE, opaque: 2, rc: 0
690 */
691probe libcouchbase.kv.observe.end =
692    process("${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/libcouchbase.so.${LCB_SONAME_FULL}").mark("observe_end")
693{
694    lcb = $arg1
695    opaque = $arg2
696    opcode = $arg3
697    latency_ns = $arg4
698    rc = $arg5
699}
700
701/**
702 * probe libcouchbase.http.begin - start of HTTP request
703 *
704 * @lcb: client instance
705 * @req: pointer to request
706 * @type: type of request, see enum lcb_http_type_t in libcouchbase/couchbase.h
707 * @method: HTTP method of request, see enum lcb_http_method_t in libcouchbase/couchbase.h
708 * @url: request URL (including schema, host and port)
709 * @host: target hostname
710 * @port: target port
711 *
712 * Example:
713 *
714 *   probe libcouchbase.http.begin {
715 *     printf("[%p] req: %p, type: %s, url: %s, host: %s, port: %s\n",
716 *         lcb, req, libcouchbase_http_type(type), url, host, port)
717 *   }
718 *
719 *
720 *   $ stap  test.stp  -c "cbc n1ql 'select 1'"
721 *   ---> Encoded query: {"statement":"select 1"}
722 *
723 *   {"$1":1},
724 *   ---> Query response finished
725 *   {
726 *   "requestID": "c36facda-b37e-43b5-a958-7f31afb8468f",
727 *   "signature": {"$1":"number"},
728 *   "results": [
729 *   ],
730 *   "status": "success",
731 *   "metrics": {"elapsedTime": "380.883µs","executionTime": "360.955µs","resultCount": 1,"resultSize": 8}
732 *   }
733 *
734 *   [0x1af6de0] req: 0x1b12250, type: N1QL, url: http://192.168.1.104:8093/query/service, host: 192.168.1.104, port: 8093
735 */
736probe libcouchbase.http.begin =
737    process("${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/libcouchbase.so.${LCB_SONAME_FULL}").mark("http_begin")
738{
739    lcb = $arg1
740    req = $arg2
741    type = $arg3
742    method = $arg4
743    url = user_string($arg5)
744    host = user_string($arg6)
745    port = user_string($arg7)
746}
747
748/**
749 * probe libcouchbase.http.end - start of HTTP request
750 *
751 * @lcb: client instance
752 * @req: pointer to request
753 * @type: type of request, see enum lcb_http_type_t in libcouchbase/couchbase.h
754 * @method: HTTP method of request, see enum lcb_http_method_t in libcouchbase/couchbase.h
755 * @url: request URL (including schema, host and port)
756 * @host: target hostname
757 * @port: target port
758 * @rc: return code from the library see libcouchbase/error.h
759 * @status: HTTP status code (number)
760 * @latency_ns: time from schedule to dispatch of the request
761 *
762 * Example:
763 *
764 *   probe libcouchbase.http.end {
765 *     printf("[%p] req: %p, type: %s, url: %s, host: %s, port: %s, rc: %d, status: %d\n",
766 *         lcb, req, libcouchbase_http_type(type), url, host, port, rc, status)
767 *   }
768 *
769 *
770 *   $ stap  test.stp  -c "cbc n1ql 'select 1'"
771 *   ---> Encoded query: {"statement":"select 1"}
772 *
773 *   {"$1":1},
774 *   ---> Query response finished
775 *   {
776 *   "requestID": "c36facda-b37e-43b5-a958-7f31afb8468f",
777 *   "signature": {"$1":"number"},
778 *   "results": [
779 *   ],
780 *   "status": "success",
781 *   "metrics": {"elapsedTime": "380.883µs","executionTime": "360.955µs","resultCount": 1,"resultSize": 8}
782 *   }
783 *
784 *   [0x1af6de0] req: 0x1b12250, type: N1QL, url: http://192.168.1.104:8093/query/service, host: 192.168.1.104, port: 8093, rc: 0, status: 200
785 */
786probe libcouchbase.http.end =
787    process("${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/libcouchbase.so.${LCB_SONAME_FULL}").mark("http_end")
788{
789    lcb = $arg1
790    req = $arg2
791    type = $arg3
792    method = $arg4
793    url = user_string($arg5)
794    host = user_string($arg6)
795    port = user_string($arg7)
796    rc = $arg8
797    status = $arg9
798    latency_us = $arg10
799}
800