Hooks
Hooks are pre-defined JavaScript functions in the scripting system that are being attached to a certain point in the network packet capture - dissect - query pipeline of Kubeshark.
Kubeshark provides OSI L4 and L7 hooks that enable running functions whenever a packet is captured or a new application-layer message is dissected.
Hooks function arguments with type object can be printed to console with the purpose of seeing the data structure of that argument, like;
console.log(JSON.stringify(data))
A couple of examples can be found at the end of this section.
Hook description includes an Arguments section that explains the hook’s arguments’ Go data structure. These Go data structures provide hints about the typings that emerge in the JavaScript runtime. Please refer to the JSON and Go page to understand how JSON encoding works in Go language if you’re not familiar with the Go language.
onPacketCaptured(info: object)
function onPacketCaptured(info) {
// Your code goes here
}
The onPacketCaptured
is an OSI L4 network hook. It is called whenever a new network packet is captured by Kubeshark.
On a busy cluster, the call frequency of this hook can go more than a 10000 times per second. Because of that; a poorly optimized onPacketCaptured
implementation can have a performance impact on the network traffic capture speed of Kubeshark. Therefore it’s logical to not call certain helpers (e.g. console.log
or vendor.slack
) and instead use this hook to aggregate data into a global variable and then handle the aggregated data in another hook or a job:
var packetCount = 0;
var totalKB = 0;
function onPacketCaptured(info) {
// Example of data aggregation, packet and KB counter
packetCount++;
totalKB += info.length / 1000;
}
function yourJob() {
// Handle `packetCount` and `totalKB` here
}
// Schedule a call to function `yourJob` every minute
jobs.schedule("example-job", "0 */1 * * * *", yourJob);
The call to hook
onPacketCaptured
does not depend on user’s action, it’s sourced from network traffic capture.
Arguments
Arguments of onPacketCaptured
hook:
info
type Info struct {
Timestamp time.Time `json:"timestamp"`
CaptureLength int `json:"captureLength"`
Length int `json:"length"`
Truncated bool `json:"truncated"`
Fragmented bool `json:"fragmented"`
}
timestamp
is the UTC timestamp of the moment that packet is captured.
captureLength
is the length of the capture.
length
is the actual length of packet.
truncated
whether the packet is truncated or not. See packet truncation for more info.
onItemCaptured(data: object)
function onItemCaptured(data) {
// Your code goes here
}
The hook onItemCaptured
is an OSI L7 network hook that is called whenever a TCP/UDP stream is captured, reassembled and successfully dissected by one of the protocol parsers of Kubeshark.
This hook is triggered less compared to the onPacketCaptured
hook, since multiple packets translate into a protocol-level message (e.g. an HTTP request-response pair, a Kafka publish, a Kafka consume or an AMQP exchange declare).
The item’s scope is determined by the corresponding application layer protocol as one can imagine. For example; an HTTP request-response pair contains a lot parameters while an AMQP exchange declare is quite a simple message.
The call to hook
onItemCaptured
does not depend on user’s action, it’s sourced from network traffic capture.
Arguments
Arguments of onItemCaptured
hook:
data
See the updated data structure: https://github.com/kubeshark/api/blob/master/api.go#L273
onItemQueried(data: object)
The hook onItemQueried
is called whenever an already captured and stored TCP/UDP stream is queried or fetched through the dashboard.
All of its other aspects are same with the onItemCaptured
hook.
The call to hook
onItemQueried
depends on user’s action, it’s not sourced from network traffic capture.
Arguments
Same as onItemCaptured
hook.
onJobPassed(tag: string, cron: string, limit: number)
function onJobPassed(tag, cron, limit) {
// Your code goes here
}
The hook onJobPassed
is called whenever a job passes.
Arguments
tag
is job tag.
cron
is the cron statement.
limit
is the limit of job runs.
onJobFailed(tag: string, cron: string, limit: number)
function onJobFailed(tag, cron, limit, err) {
// Your code goes here
}
The hook onJobFailed
is called whenever a job fails.
Arguments
tag
is job tag.
cron
is the cron statement.
limit
is the limit of job runs.
err
is the error message.
Example values of the data
argument
Here are some example values of the data
argument that being used in
onItemCaptured
and onItemQueried
hooks:
HTTP
{
"dst": {
"ip": "10.0.0.99",
"name": "",
"port": "8086"
},
"elapsedTime": 23,
"failed": false,
"id": "192.168.49.2:8897/000000025258.pcap-0",
"index": 0,
"namespace": "default",
"node": {
"ip": "192.168.49.2",
"name": "my-cluster"
},
"outgoing": false,
"passed": false,
"protocol": {
"abbr": "HTTP",
"backgroundColor": "#326de6",
"fontSize": 12,
"foregroundColor": "#ffffff",
"layer4": "tcp",
"longName": "Hypertext Transfer Protocol -- HTTP/1.1",
"macro": "http",
"name": "http",
"ports": [
"80",
"443",
"8080"
],
"priority": 0,
"referenceLink": "https://datatracker.ietf.org/doc/html/rfc2616",
"version": "1.1"
},
"request": {
"bodySize": 124,
"cookies": {},
"headers": {
"Accept-Encoding": "gzip",
"Authorization": "Token edO4nlXbD5cfx8nw9_94LMO4tvGJ_xeMQMiFc6J_DNYFAGRe0YIgG8gz98UwDKOa6otCzml3SNw_c5TiDuB4eA==",
"Content-Length": "124",
"Host": "10.0.0.99:8086",
"User-Agent": "influxdb-client-go/2.12.2 (linux; amd64)"
},
"headersSize": -1,
"httpVersion": "HTTP/1.1",
"method": "POST",
"path": "/api/v2/write",
"pathSegments": [
"api",
"v2",
"write"
],
"postData": {
"mimeType": "",
"params": [],
"text": "PerformanceKPIs,namespace=sock-shop,path=/basket.html,service=front-end.sock-shop latency=51,status=200 1678675066165748213\n"
},
"queryString": {
"bucket": "Metrics",
"org": "Kubeshark",
"precision": "ns"
},
"targetUri": "/api/v2/write?bucket=Metrics&org=Kubeshark&precision=ns",
"url": "/api/v2/write?bucket=Metrics&org=Kubeshark&precision=ns"
},
"requestSize": 428,
"response": {
"bodySize": 0,
"content": {
"encoding": "base64",
"mimeType": "",
"size": 0
},
"cookies": {},
"headers": {
"Date": "Mon, 13 Mar 2023 02:37:46 GMT",
"X-Influxdb-Build": "OSS",
"X-Influxdb-Version": "2.6.1"
},
"headersSize": -1,
"httpVersion": "HTTP/1.1",
"redirectURL": "",
"status": 204,
"statusText": "No Content"
},
"responseSize": 114,
"src": {
"ip": "192.168.49.2",
"name": "kubernetes.default",
"port": "36848"
},
"startTime": "2023-03-13T02:37:46.172360504Z",
"stream": "000000025258.pcap",
"timestamp": 1678675066172,
"tls": false,
"worker": "192.168.49.2:30001"
}
DNS
{
"dst": {
"ip": "172.17.0.3",
"name": "kube-dns.kube-system",
"port": "53"
},
"elapsedTime": 0,
"failed": false,
"id": "192.168.49.2:8897/000000025277_udp.pcap-0",
"index": 0,
"namespace": "kube-system",
"node": {
"ip": "192.168.49.2",
"name": "my-cluster"
},
"outgoing": false,
"passed": false,
"protocol": {
"abbr": "DNS",
"backgroundColor": "#606060",
"fontSize": 12,
"foregroundColor": "#ffffff",
"layer4": "udp",
"longName": "Domain Name System",
"macro": "dns",
"name": "dns",
"ports": [],
"priority": 4,
"referenceLink": "https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml",
"version": "0"
},
"request": {
"opCode": "Query",
"questions": [
{
"class": "IN",
"name": "session-db.sock-shop.svc.cluster.local",
"type": "A"
}
]
},
"requestSize": 154,
"response": {
"answers": [
{
"class": "IN",
"cname": "",
"ip": "10.101.46.75",
"mx": "",
"name": "session-db.sock-shop.svc.cluster.local",
"ns": "",
"opt": "",
"ptr": "",
"soa": "",
"srv": "",
"ttl": 24,
"txts": "",
"type": "A",
"uri": ""
}
],
"code": "No Error"
},
"responseSize": 154,
"src": {
"ip": "172.17.0.1",
"name": "",
"port": "33305"
},
"startTime": "2023-03-13T02:37:49.958762876Z",
"stream": "000000025277_udp.pcap",
"timestamp": 1678675069958,
"tls": false,
"worker": "192.168.49.2:30001"
}