Exemple #1
0
  def DisableSlowestSupplementalServers(self, multiplier=TOO_DISTANT_MULTIPLIER, max_servers=None,
                                        prefer_asn=None):
    """Disable servers who's fastest duration is multiplier * average of best 10 servers."""
    if not max_servers:
      max_servers = self.max_servers_to_check

    supplemental_servers = self.enabled_supplemental
    fastest = [x for x in self.SortEnabledByFastest()][:10]
    best_10 = util.CalculateListAverage([x.fastest_check_duration for x in fastest])
    cutoff = best_10 * multiplier
    self.msg("Removing secondary nameservers slower than %0.2fms (max=%s)" % (cutoff, max_servers))

    for (idx, ns) in enumerate(self.SortEnabledByFastest()):
      hide = False
      if ns not in supplemental_servers:
        continue

      if ns.fastest_check_duration > cutoff:
        hide = True
      if idx > max_servers:
        hide = True

      if hide:
        matches = ns.MatchesTags(nameserver.PROVIDER_TAGS)
        if matches:
          self.msg("%s seems slow, but has tag: %s" % (ns, matches))
        else:
          ns.tags.add('hidden')
Exemple #2
0
    def ComputeAverages(self):
        """Process all runs for all hosts, yielding an average for each host."""
        if len(self.results) in self.cached_averages:
            return self.cached_averages[len(self.results)]

        records = []
        for ns in self.results:
            if ns.disabled:
                continue
            failure_count = 0
            nx_count = 0
            run_averages = []

            for test_run in self.results[ns]:
                # x: record, req_type, duration, response
                total_count = len(test_run)
                failure_count += len([x for x in test_run if not x[3]])
                nx_count += len(
                    [x for x in test_run if x[3] and not x[3].answer])
                duration = sum([x[2] for x in test_run])
                run_averages.append(duration / len(test_run))

            # This appears to be a safe use of averaging averages
            overall_average = util.CalculateListAverage(run_averages)
            (fastest,
             slowest) = self.FastestAndSlowestDurationForNameServer(ns)

            records.append((ns, overall_average, run_averages, fastest,
                            slowest, failure_count, nx_count, total_count))
        self.cached_averages[len(self.results)] = records
        return self.cached_averages[len(self.results)]
Exemple #3
0
    def CheckConnectionQuality(self):
        """Look how healthy our DNS connection quality. Averages check durations."""

        is_connection_offline = True
        durations = []
        self.msg('Checking query interception status...')
        (intercepted, i_duration) = self.GetInterceptionStatus()
        if i_duration:
            is_connection_offline = False

        durations.append(i_duration)

        try_count = 3
        for i in range(try_count):
            self.msg('Checking connection quality',
                     count=i + 1,
                     total=try_count)
            if self.primary:
                (broken, unused_warning,
                 n_duration) = self.GetNegativeResponseDuration()
                if not broken:
                    is_connection_offline = False
                durations.append(n_duration)

            (unused_response, g_duration,
             error_msg) = self.GetGoogleResponseDuration()
            durations.append(g_duration)
            if not error_msg:
                is_connection_offline = False

            if is_connection_offline and (i + 1) != try_count:
                self.msg(
                    'The internet connection appears to be offline (%s of %s)'
                    % (i + 1, try_count))
            time.sleep(0.2)

        if is_connection_offline:
            raise OfflineConnection(
                'It would appear that your internet connection is offline. '
                'namebench is not gettng a response for DNS queries to '
                '%s, %s, or %s.' % (self.primary.ip, GOOGLE_NS, OPENDNS_NS))

        duration = util.CalculateListAverage(durations)
        congestion = duration / EXPECTED_CONGESTION_DURATION
        self.msg('Congestion level is %2.2fX (check duration: %2.2fms)' %
                 (congestion, duration))
        if congestion > 1:
            # multiplier is
            multiplier = 1 + ((congestion - 1) * CONGESTION_OFFSET_MULTIPLIER)
            if multiplier > MAX_CONGESTION_MULTIPLIER:
                multiplier = MAX_CONGESTION_MULTIPLIER
        else:
            multiplier = 1
        return (intercepted, congestion, multiplier, duration)
Exemple #4
0
    def CheckConnectionQuality(self):
        """Look how healthy our DNS connection quality. Averages check durations."""

        is_connection_offline = True
        self.msg('Checking query interception status...')
        odns = providers.OpenDNS()
        (intercepted, i_duration) = odns.InterceptionStateWithDuration()
        if i_duration:
            is_connection_offline = False

        durations = []
        try_count = 3
        for i in range(try_count):
            self.msg('Checking connection quality',
                     count=i + 1,
                     total=try_count)
            if self.primary:
                (broken, unused_warning,
                 n_duration) = self.GetNegativeResponseDuration()
                if not broken:
                    is_connection_offline = False
                    durations.append(n_duration)

            (unused_response, g_duration,
             error_msg) = self.GetGoogleResponseDuration()

            if not error_msg:
                durations.append(g_duration)
                is_connection_offline = False

            if is_connection_offline and (i + 1) != try_count:
                self.msg(
                    'The internet connection appears to be offline (%s of %s)'
                    % (i + 1, try_count))
            time.sleep(0.2)

        if is_connection_offline:
            raise OfflineConnection(
                'It would appear that your internet connection is offline.'
                'namebench is not gettng a response for DNS queries to '
                '%s, %s, or %s.' %
                (self.primary.ip, providers.GOOGLE_IP, providers.OPENDNS_IP))
        avg_latency_s = util.CalculateListAverage(durations) / 1000.0
        max_latency_s = max(durations) / 1000.0
        self.msg("Average DNS lookup latency: %.2fs Maximum: %.2fs" %
                 (avg_latency_s, max_latency_s))
        return (intercepted, avg_latency_s, max_latency_s)
Exemple #5
0
    def DisableDistantServers(self,
                              multiplier=TOO_DISTANT_MULTIPLIER,
                              max_servers=MAX_NEARBY_SERVERS):
        """Disable servers who's fastest duration is multiplier * average of best 10 servers."""

        self.RemoveBrokenServers(delete_unwanted=True)
        secondaries = self.secondaries
        fastest = [x for x in self.SortByFastest() if not x.disabled][:10]
        best_10 = util.CalculateListAverage(
            [x.fastest_check_duration for x in fastest])
        cutoff = best_10 * multiplier
        self.msg(
            "Removing secondary nameservers slower than %0.2fms (max=%s)" %
            (cutoff, max_servers))
        for idx, ns in enumerate(secondaries):
            if (ns.fastest_check_duration > cutoff) or idx > max_servers:
                self.remove(ns)
Exemple #6
0
    def _GenerateNameServerSummary(self):
        if self.cached_summary:
            return self.cached_summary

        nsdata = {}
        sorted_averages = sorted(self.ComputeAverages(),
                                 key=operator.itemgetter(1))
        placed_at = -1
        fastest = {}
        fastest_nonglobal = {}
        reference = {}

        # Fill in basic information for all nameservers, even those without scores.
        fake_position = 1000
        for ns in sorted(self.nameservers,
                         key=operator.attrgetter('check_average')):
            fake_position += 1

            nsdata[ns] = {
                'ip': ns.ip,
                'name': ns.name,
                'hostname': ns.hostname,
                'version': ns.version,
                'node_ids': list(ns.node_ids),
                'sys_position': ns.system_position,
                'is_failure_prone': ns.is_failure_prone,
                'duration_min': float(ns.fastest_check_duration),
                'is_global': ns.is_global,
                'is_regional': ns.is_regional,
                'is_custom': ns.is_custom,
                'is_reference': False,
                'is_disabled': bool(ns.disabled),
                'check_average': ns.check_average,
                'error_count': ns.error_count,
                'timeout_count': ns.timeout_count,
                'notes': url_map.CreateNoteUrlTuples(ns.notes),
                'port_behavior': ns.port_behavior,
                'position': fake_position
            }

        # Fill the scores in.
        for (ns, unused_avg, run_averages, fastest, slowest, unused_failures,
             nx_count, unused_total) in sorted_averages:
            placed_at += 1

            durations = []
            for _ in self.results[ns]:
                durations.append([x[2] for x in self.results[ns][0]])

            nsdata[ns].update({
                'position':
                placed_at,
                'overall_average':
                util.CalculateListAverage(run_averages),
                'averages':
                run_averages,
                'duration_min':
                float(fastest),
                'duration_max':
                slowest,
                'nx_count':
                nx_count,
                'durations':
                durations,
                'index':
                self._GenerateIndexSummary(ns),
            })
            # Determine which nameserver to refer to for improvement scoring
            if not ns.disabled:
                if ns.system_position == 0:
                    reference = ns
                elif not fastest_nonglobal and not ns.is_global:
                    fastest_nonglobal = ns

        # If no reference was found, use the fastest non-global nameserver record.
        if not reference:
            if fastest_nonglobal:
                reference = fastest_nonglobal
            else:
                # The second ns.
                reference = sorted_averages[1][0]

        # Update the improvement scores for each nameserver.
        for ns in nsdata:
            if nsdata[ns]['ip'] != nsdata[reference]['ip']:
                if 'overall_average' in nsdata[ns]:
                    nsdata[ns]['diff'] = (
                        (nsdata[reference]['overall_average'] /
                         nsdata[ns]['overall_average']) - 1) * 100
            else:
                nsdata[ns]['is_reference'] = True


#      print "--- DEBUG: %s ---" % ns
#      print nsdata[ns]
#      if 'index' in nsdata[ns]:
#        print "index length: %s" % len(nsdata[ns]['index'])
#      print ""

        self.cached_summary = sorted(nsdata.values(),
                                     key=operator.itemgetter('position'))
        return self.cached_summary
Exemple #7
0
 def testCalculateListAverage(self):
     self.assertEqual(util.CalculateListAverage([3, 2, 2]),
                      2.3333333333333335)
Exemple #8
0
 def check_average(self):
   # If we only have a ping result, sort by it. Otherwise, use all non-ping results.
   if len(self.checks) == 1:
     return self.checks[0][3]
   else:
     return util.CalculateListAverage([x[3] for x in self.checks[1:]])
Exemple #9
0
 def check_average(self):
     return util.CalculateListAverage(
         [x.check_average for x in self if not x.disabled])