| OLD | NEW |
| 1 # This file is part of Buildbot. Buildbot is free software: you can | 1 # This file is part of Buildbot. Buildbot is free software: you can |
| 2 # redistribute it and/or modify it under the terms of the GNU General Public | 2 # redistribute it and/or modify it under the terms of the GNU General Public |
| 3 # License as published by the Free Software Foundation, version 2. | 3 # License as published by the Free Software Foundation, version 2. |
| 4 # | 4 # |
| 5 # This program is distributed in the hope that it will be useful, but WITHOUT | 5 # This program is distributed in the hope that it will be useful, but WITHOUT |
| 6 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | 6 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
| 7 # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more | 7 # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more |
| 8 # details. | 8 # details. |
| 9 # | 9 # |
| 10 # You should have received a copy of the GNU General Public License along with | 10 # You should have received a copy of the GNU General Public License along with |
| 11 # this program; if not, write to the Free Software Foundation, Inc., 51 | 11 # this program; if not, write to the Free Software Foundation, Inc., 51 |
| 12 # Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | 12 # Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
| 13 # | 13 # |
| 14 # Copyright Buildbot Team Members | 14 # Copyright Buildbot Team Members |
| 15 | 15 |
| 16 | 16 |
| 17 import os, time, weakref | 17 import os, weakref |
| 18 | 18 |
| 19 from zope.interface import implements | 19 from zope.interface import implements |
| 20 from twisted.python import log | 20 from twisted.python import log |
| 21 from twisted.application import strports, service | 21 from twisted.application import strports, service |
| 22 from twisted.web import server, distrib, static | 22 from twisted.web import server, distrib, static |
| 23 from twisted.spread import pb | 23 from twisted.spread import pb |
| 24 from twisted.web.util import Redirect | 24 from twisted.web.util import Redirect |
| 25 | 25 |
| 26 from buildbot.interfaces import IStatusReceiver | 26 from buildbot.interfaces import IStatusReceiver |
| 27 | 27 |
| 28 from buildbot.status.web.base import StaticFile, createJinjaEnv | 28 from buildbot.status.web.base import StaticFile, createJinjaEnv |
| 29 from buildbot.status.web.feeds import Rss20StatusResource, \ | 29 from buildbot.status.web.feeds import Rss20StatusResource, \ |
| 30 Atom10StatusResource | 30 Atom10StatusResource |
| 31 from buildbot.status.web.waterfall import WaterfallStatusResource | 31 from buildbot.status.web.waterfall import WaterfallStatusResource |
| 32 from buildbot.status.web.console import ConsoleStatusResource | 32 from buildbot.status.web.console import ConsoleStatusResource |
| 33 from buildbot.status.web.olpb import OneLinePerBuild | 33 from buildbot.status.web.olpb import OneLinePerBuild |
| 34 from buildbot.status.web.grid import GridStatusResource, TransposedGridStatusRes
ource | 34 from buildbot.status.web.grid import GridStatusResource, TransposedGridStatusRes
ource |
| 35 from buildbot.status.web.changes import ChangesResource | 35 from buildbot.status.web.changes import ChangesResource |
| 36 from buildbot.status.web.builder import BuildersResource | 36 from buildbot.status.web.builder import BuildersResource |
| 37 from buildbot.status.web.buildstatus import BuildStatusStatusResource | 37 from buildbot.status.web.buildstatus import BuildStatusStatusResource |
| 38 from buildbot.status.web.slaves import BuildSlavesResource | 38 from buildbot.status.web.slaves import BuildSlavesResource |
| 39 from buildbot.status.web.status_json import JsonStatusResource | 39 from buildbot.status.web.status_json import JsonStatusResource |
| 40 from buildbot.status.web.about import AboutBuildbot | 40 from buildbot.status.web.about import AboutBuildbot |
| 41 from buildbot.status.web.authz import Authz | 41 from buildbot.status.web.authz import Authz |
| 42 from buildbot.status.web.auth import AuthFailResource | 42 from buildbot.status.web.auth import AuthFailResource |
| 43 from buildbot.status.web.root import RootPage | 43 from buildbot.status.web.root import RootPage |
| 44 from buildbot.status.web.change_hook import ChangeHookResource | 44 from buildbot.status.web.change_hook import ChangeHookResource |
| 45 | 45 |
| 46 from infra_libs.ts_mon.common import http_metrics | |
| 47 | |
| 48 # this class contains the WebStatus class. Basic utilities are in base.py, | 46 # this class contains the WebStatus class. Basic utilities are in base.py, |
| 49 # and specific pages are each in their own module. | 47 # and specific pages are each in their own module. |
| 50 | 48 |
| 51 class WebStatus(service.MultiService): | 49 class WebStatus(service.MultiService): |
| 52 implements(IStatusReceiver) | 50 implements(IStatusReceiver) |
| 53 # TODO: IStatusReceiver is really about things which subscribe to hear | 51 # TODO: IStatusReceiver is really about things which subscribe to hear |
| 54 # about buildbot events. We need a different interface (perhaps a parent | 52 # about buildbot events. We need a different interface (perhaps a parent |
| 55 # of IStatusReceiver) for status targets that don't subscribe, like the | 53 # of IStatusReceiver) for status targets that don't subscribe, like the |
| 56 # WebStatus class. buildbot.master.BuildMaster.loadConfig:737 asserts | 54 # WebStatus class. buildbot.master.BuildMaster.loadConfig:737 asserts |
| 57 # that everything in c['status'] provides IStatusReceiver, but really it | 55 # that everything in c['status'] provides IStatusReceiver, but really it |
| (...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 381 def either(a,b): # a if a else b for py2.4 | 379 def either(a,b): # a if a else b for py2.4 |
| 382 if a: | 380 if a: |
| 383 return a | 381 return a |
| 384 else: | 382 else: |
| 385 return b | 383 return b |
| 386 | 384 |
| 387 rotateLength = either(self.logRotateLength, self.master.log_rotation.rot
ateLength) | 385 rotateLength = either(self.logRotateLength, self.master.log_rotation.rot
ateLength) |
| 388 maxRotatedFiles = either(self.maxRotatedFiles, self.master.log_rotation.
maxRotatedFiles) | 386 maxRotatedFiles = either(self.maxRotatedFiles, self.master.log_rotation.
maxRotatedFiles) |
| 389 | 387 |
| 390 if not self.site: | 388 if not self.site: |
| 391 | 389 |
| 392 class MonitoredRequest(server.Request): | |
| 393 def __init__(self, *args, **kwargs): | |
| 394 server.Request.__init__(self, *args, **kwargs) | |
| 395 self.startTime = time.time() | |
| 396 | |
| 397 def render(self, resrc): | |
| 398 self.resourceClassName = resrc.__class__.__name__ | |
| 399 server.Request.render(self, resrc) | |
| 400 | |
| 401 class RotateLogSite(server.Site): | 390 class RotateLogSite(server.Site): |
| 402 requestFactory = MonitoredRequest | |
| 403 | |
| 404 def log(self, request): | |
| 405 server.Site.log(self, request) | |
| 406 | |
| 407 durationMsec = 1000 * (time.time() - request.startTime) | |
| 408 | |
| 409 requestLength = request.getHeader('content-length') | |
| 410 if requestLength is not None: | |
| 411 requestLength = int(requestLength) | |
| 412 | |
| 413 http_metrics.update_http_server_metrics( | |
| 414 request.resourceClassName, | |
| 415 request.code, | |
| 416 durationMsec, | |
| 417 requestLength, | |
| 418 request.sentLength, | |
| 419 request.getHeader('user-agent') or '') | |
| 420 | |
| 421 def _openLogFile(self, path): | 391 def _openLogFile(self, path): |
| 422 try: | 392 try: |
| 423 from twisted.python.logfile import LogFile | 393 from twisted.python.logfile import LogFile |
| 424 log.msg("Setting up http.log rotating %s files of %s byt
es each" % | 394 log.msg("Setting up http.log rotating %s files of %s byt
es each" % |
| 425 (maxRotatedFiles, rotateLength)) | 395 (maxRotatedFiles, rotateLength)) |
| 426 if hasattr(LogFile, "fromFullPath"): # not present in Tw
isted-2.5.0 | 396 if hasattr(LogFile, "fromFullPath"): # not present in Tw
isted-2.5.0 |
| 427 return LogFile.fromFullPath(path, rotateLength=rotat
eLength, maxRotatedFiles=maxRotatedFiles) | 397 return LogFile.fromFullPath(path, rotateLength=rotat
eLength, maxRotatedFiles=maxRotatedFiles) |
| 428 else: | 398 else: |
| 429 log.msg("WebStatus: rotated http logs are not suppor
ted on this version of Twisted") | 399 log.msg("WebStatus: rotated http logs are not suppor
ted on this version of Twisted") |
| 430 except ImportError, e: | 400 except ImportError, e: |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 517 # What happened to getControl?! | 487 # What happened to getControl?! |
| 518 # | 488 # |
| 519 # instead of passing control objects all over the place in the web | 489 # instead of passing control objects all over the place in the web |
| 520 # code, at the few places where a control instance is required we | 490 # code, at the few places where a control instance is required we |
| 521 # find the requisite object manually, starting at the buildmaster. | 491 # find the requisite object manually, starting at the buildmaster. |
| 522 # This is in preparation for removal of the IControl hierarchy | 492 # This is in preparation for removal of the IControl hierarchy |
| 523 # entirely. | 493 # entirely. |
| 524 | 494 |
| 525 # resources can get access to the IStatus by calling | 495 # resources can get access to the IStatus by calling |
| 526 # request.site.buildbot_service.getStatus() | 496 # request.site.buildbot_service.getStatus() |
| OLD | NEW |