Browse Source

Updated netprobe, and added netprobe.log to auto alias

Miguel Angel Ajo 3 years ago
parent
commit
e901627f16
3 changed files with 54 additions and 11 deletions
  1. 1
    1
      README.rst
  2. 1
    0
      oslogmerger/oslogmerger.py
  3. 52
    10
      oslogmerger/probes/netprobe.py

+ 1
- 1
README.rst View File

@@ -261,4 +261,4 @@ Usage details::
261 261
       --tcpdump-filter TCPDUMP_FILTER, -t TCPDUMP_FILTER
262 262
       --check-interval CHECK_INTERVAL, -i CHECK_INTERVAL
263 263
                             The interval between interface checks
264
-
264
+      --output-file OUTPUT_FILE, -o OUTPUT_FILE

+ 1
- 0
oslogmerger/oslogmerger.py View File

@@ -60,6 +60,7 @@ FILE_MAP = {
60 60
     'openvswitch-agent': 'VSWI',
61 61
     'server': 'API',
62 62
     'linuxbridge-agent': 'SVC',
63
+    'netprobe': 'NET',
63 64
     # Heat
64 65
     'heat-api': 'API',
65 66
     'heat-engine': 'ENG',

+ 52
- 10
oslogmerger/probes/netprobe.py View File

@@ -3,7 +3,10 @@ from __future__ import print_function
3 3
 
4 4
 import argparse
5 5
 import datetime
6
+import fcntl
7
+import os
6 8
 import re
9
+import select
7 10
 import sys
8 11
 import subprocess
9 12
 import time
@@ -12,15 +15,38 @@ import threading
12 15
 __version__ = '0.0.1'
13 16
 
14 17
 INTERFACE_RE = re.compile('\d+: (.+):')
15
-DEFAULT_CHECK_INTERVAL = 5
16
-DEFAULT_INTERFACE_RE = "tap.*|qbr.*|qg-\.*|qr-\.*"
18
+DEFAULT_CHECK_INTERVAL = 1
19
+DEFAULT_INTERFACE_RE = "tap.*|qg-\.*|qr-\.*"
17 20
 DEFAULT_TCPDUMP_FILTER = '(arp or rarp) or (udp and (port 67 or port 68))' + \
18 21
                          ' or icmp or icmp6'
22
+DEFAULT_OUTPUT_FILE = '/var/log/neutron/netprobe.log'
23
+
24
+output = sys.stdout
25
+
26
+
27
+def _execute(cmd):
28
+    _PIPE = subprocess.PIPE
29
+    obj = subprocess.Popen(cmd, stdin=_PIPE, stdout=_PIPE, close_fds=True,
30
+                           shell=False)
31
+    result = obj.communicate()
32
+    obj.stdin.close()
33
+    (stdout, stderr) = result
34
+    return stdout
35
+
36
+
37
+def execute(cmd):
38
+    # FIXME: super nasty hack to avoid a deadlock in the above function when
39
+    #        calling ip link, I have spent 4 hours debugging it, enough for
40
+    #        today...
41
+    cmd_str = ' '.join(cmd)
42
+    os.system(cmd_str + ' >/tmp/exec_out')
43
+    with open('/tmp/exec_out', 'r') as f:
44
+        return f.read()
19 45
 
20 46
 
21 47
 def netns():
22 48
     return filter(lambda line: len(line) > 0,
23
-                  subprocess.check_output(['ip', 'netns']).split('\n'))
49
+                  execute(['ip', 'netns']).split('\n'))
24 50
 
25 51
 
26 52
 def _netns_cmd(netns=None):
@@ -32,7 +58,7 @@ def _netns_cmd(netns=None):
32 58
 
33 59
 def interfaces(netns=None):
34 60
     cmd = _netns_cmd(netns) + ['ip', 'link']
35
-    out = subprocess.check_output(cmd).split('\n')
61
+    out = execute(cmd).split('\n')
36 62
     not_down = "\n".join(filter(lambda line: line.find(' DOWN ') == -1, out))
37 63
     return INTERFACE_RE.findall(not_down)
38 64
 
@@ -52,10 +78,18 @@ def spawn_tcpdump(interface, netns=None,
52 78
     tcpdump = subprocess.Popen(cmd, bufsize=0,
53 79
                                stdout=subprocess.PIPE,
54 80
                                stderr=subprocess.PIPE)
81
+    fd = tcpdump.stdout.fileno()
82
+    fl = fcntl.fcntl(fd, fcntl.F_GETFL)
83
+    fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)
55 84
     print(_time_now(), interface,
56
-          "started dumping with filter {}".format(filters))
85
+          "started dumping with filter {}".format(filters),
86
+          file=output)
57 87
     while True:
58
-        out = tcpdump.stdout.readline()
88
+        reads, writes, excs = select.select([tcpdump.stdout], [], [])
89
+        try:
90
+            out = reads[0].readline()
91
+        except:
92
+            continue
59 93
         if out == '':
60 94
             break
61 95
         line = out.rstrip()
@@ -64,7 +98,8 @@ def spawn_tcpdump(interface, netns=None,
64 98
         tcpdump_trace = ' '.join(chunks[1:])
65 99
         # FIXME: _date_now + tcpdump_timestamp can be raceful at the
66 100
         #        end of the day
67
-        print(_date_now(), timestamp, interface, tcpdump_trace)
101
+        print(_date_now(), timestamp, interface, tcpdump_trace,
102
+              file=output)
68 103
 
69 104
 
70 105
 def parse_args():
@@ -98,6 +133,10 @@ the tcpdumps goes in a single openstack-like log.
98 133
                         dest='check_interval',
99 134
                         help='The interval between interface checks')
100 135
 
136
+    parser.add_argument('--output-file', '-o',
137
+                        default=DEFAULT_OUTPUT_FILE,
138
+                        dest='output_file')
139
+
101 140
     return parser.parse_args()
102 141
 
103 142
 
@@ -117,7 +156,6 @@ def scan_loop(args):
117 156
     netdev_re = re.compile(args.netdev_regex)
118 157
     tcpdump_filter = args.tcpdump_filter
119 158
     while True:
120
-        print(_time_now(), "checking interfaces", file=sys.stderr)
121 159
         namespaces = filter(netns_re.match, netns()) + [None]
122 160
         for namespace in namespaces:
123 161
             ifs = filter(netdev_re.match, interfaces(namespace))
@@ -126,7 +164,7 @@ def scan_loop(args):
126 164
                 if name not in tracked_ifs:
127 165
                     print(_time_now(),
128 166
                           "Watching interface {}".format(name),
129
-                          file=sys.stderr)
167
+                          file=output)
130 168
                     tracked_ifs[name] = create_tcpdump_thread(interface,
131 169
                                                               namespace,
132 170
                                                               tcpdump_filter,
@@ -135,14 +173,18 @@ def scan_loop(args):
135 173
         for thread_name, thread in tracked_ifs.items():
136 174
             if not thread.is_alive():
137 175
                 print(_time_now(),
138
-                      "Interface {} went away".format(thread_name))
176
+                      "Interface {} went away".format(thread_name),
177
+                      file=output)
139 178
                 tracked_ifs.pop(thread_name).join()
140 179
 
141 180
         time.sleep(args.check_interval)
142 181
 
143 182
 
144 183
 def main():
184
+    global output
145 185
     args = parse_args()
186
+    print(args.output_file)
187
+    output = open(args.output_file, 'w', 0)
146 188
     scan_loop(args)
147 189
 
148 190
 if __name__ == '__main__':

Loading…
Cancel
Save