[CalendarServer-changes] [558] CalendarServer/branches/caladmin-tool/caladmin

source_changes at macosforge.org source_changes at macosforge.org
Wed Nov 22 12:09:55 PST 2006


Revision: 558
          http://trac.macosforge.org/projects/calendarserver/changeset/558
Author:   dreid at apple.com
Date:     2006-11-22 12:09:55 -0800 (Wed, 22 Nov 2006)

Log Message:
-----------
Basic CLF log analysis

Modified Paths:
--------------
    CalendarServer/branches/caladmin-tool/caladmin/options.py
    CalendarServer/branches/caladmin-tool/caladmin/principals.py
    CalendarServer/branches/caladmin-tool/caladmin/stats.py

Added Paths:
-----------
    CalendarServer/branches/caladmin-tool/caladmin/logs.py

Added: CalendarServer/branches/caladmin-tool/caladmin/logs.py
===================================================================
--- CalendarServer/branches/caladmin-tool/caladmin/logs.py	                        (rev 0)
+++ CalendarServer/branches/caladmin-tool/caladmin/logs.py	2006-11-22 20:09:55 UTC (rev 558)
@@ -0,0 +1,138 @@
+##
+# Copyright (c) 2006 Apple Computer, Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# DRI: David Reid, dreid at apple.com
+##
+"""
+ Log Stats:
+  # Invitations sent per day/week/month
+  # bytes out (bytes in not provided in the current log format.)/
+  # requests
+  user agents
+
+"""
+
+import plistlib
+
+statsTemplate = plistlib.Dict(
+    BytesOut=0, 
+    Requests=plistlib.Dict(
+        PROPFIND=0,
+        ), 
+    Invitations=plistlib.Dict(
+        day=0, 
+        week=0, 
+        month=0, 
+        ),
+    UserAgents=plistlib.Dict(),
+    )
+
+
+class Stats(object):
+    def __init__(self, fp):
+        self.fp = fp
+
+        if self.fp.exists():
+            self._data = plistlib.readPlist(self.fp.path)
+        else:
+            self._data = statsTemplate
+            self.save()
+
+    def addBytes(self, bytes):
+        self._data.BytesOut += bytes
+
+    def addRequest(self, request):
+        if request in self._data.Requests:
+            self._data.Requests[request] += 1
+        else:
+            self._data.Requests[request] = 1
+
+    def addUserAgent(self, useragent):
+        if useragent in self._data.UserAgents:
+            self._data.UserAgents[useragent] += 1
+        else:
+            self._data.UserAgents[useragent] = 1
+
+    def save(self):
+        plistlib.writePlist(self._data, self.fp.path)
+
+
+NORMAL = 1
+INDATE = 2
+INSTRING = 3
+
+
+def parseCLFLine(line):
+    state = NORMAL
+    elements = []
+    
+    rest = []
+
+    for c in line:
+        if c == ' ':
+            if state == NORMAL:
+                elements.append(''.join(rest))
+                rest = []
+
+            elif state == INSTRING or state == INDATE:
+                rest.append(c)
+                    
+        elif c == '[':
+            if state != INSTRING:
+                state = INDATE
+                        
+        elif c == ']':
+            if state == INDATE:
+                state = NORMAL
+
+        elif c == '"':
+            if state == INSTRING:
+                state = NORMAL
+            else:
+                state = INSTRING
+        elif c == '\n':
+            if state == NORMAL:
+                elements.append(''.join(rest))
+                rest = []
+
+        else:
+            rest.append(c)
+
+    return elements
+
+                    
+class LogAction(object):
+    def __init__(self, config):
+        self.config = config
+
+        self.logfile = self.config['logfile']
+        self.stats = Stats(self.config['stats'])
+
+    def run(self):
+        for line in self.logfile.open():
+            if line.startswith('Log opened') or line.startswith('Log closed'):
+                continue
+            else:
+                pline = parseCLFLine(line)
+
+                print pline
+
+                self.stats.addBytes(int(pline[6]))
+                self.stats.addRequest(pline[4].split(' ')[0])
+
+                if len(pline) > 7:
+                    self.stats.addUserAgent(pline[8])
+        
+        self.stats.save()

Modified: CalendarServer/branches/caladmin-tool/caladmin/options.py
===================================================================
--- CalendarServer/branches/caladmin-tool/caladmin/options.py	2006-11-22 19:58:19 UTC (rev 557)
+++ CalendarServer/branches/caladmin-tool/caladmin/options.py	2006-11-22 20:09:55 UTC (rev 558)
@@ -130,33 +130,48 @@
 
 registerCommand(StatsOptions)
 
-
 from twisted.python import filepath
+from twistedcaldav.caldavd import caldavd_defaults
 
 class LogOptions(SubCommand):
     name = 'logs'
     help = ('Gather and report useful information from the logfiles.')
     action = 'caladmin.logs.LogAction'
 
+    optFlags = [
+        ['no-output', 'n', 'Do not output anything to stdout'],
+        PARAM_HUMAN,
+        PARAM_KILO,
+        PARAM_MEGA,
+        PARAM_GIGA,
+        ]
+    
+    optParameters = [
+        ['stats', 's', 'stats.plist',
+         ('Path to destination file for statistics. Note: Stats will be '
+          'updated if this file already exists.')],
+        ]
+
     def __init__(self):
         SubCommand.__init__(self)
 
         self['logfile'] = None
 
-    def opt_logfile(self, logfile):
-        """Path to the log file to be analyzed.
-        [default: /var/log/caldavd/server.log]
-        """ 
+    def opt_logfile(self, path):
+        """Path to input logfile
+        """
 
-        self['logfile'] = filepath.FilePath(logfile)
+        self['logfile'] = path
 
-    opt_l = opt_logfile
-
     def postOptions(self):
         if not self['logfile']:
             self['logfile'] = filepath.FilePath(
                 self.parent.config['ServerLogFile'])
+        else:
+            self['logfile'] = filepath.FilePath(self['logfile'])
 
+        self['stats'] = filepath.FilePath(self['stats'])
+
         SubCommand.postOptions(self)
 
 registerCommand(LogOptions)

Modified: CalendarServer/branches/caladmin-tool/caladmin/principals.py
===================================================================
--- CalendarServer/branches/caladmin-tool/caladmin/principals.py	2006-11-22 19:58:19 UTC (rev 557)
+++ CalendarServer/branches/caladmin-tool/caladmin/principals.py	2006-11-22 20:09:55 UTC (rev 558)
@@ -15,6 +15,13 @@
 #
 # DRI: David Reid, dreid at apple.com
 ##
+"""
+ Account Stats: 
+  # of calendars
+  # of events
+  # storage used (including things that don't count against quota?)
+  Last login?
+"""
 
 from caladmin import util
 

Modified: CalendarServer/branches/caladmin-tool/caladmin/stats.py
===================================================================
--- CalendarServer/branches/caladmin-tool/caladmin/stats.py	2006-11-22 19:58:19 UTC (rev 557)
+++ CalendarServer/branches/caladmin-tool/caladmin/stats.py	2006-11-22 20:09:55 UTC (rev 558)
@@ -19,23 +19,11 @@
 """
 Statisitcs Types:
 
- Account Stats: 
-  # of calendars
-  # of events
-  # storage used (including things that don't count against quota?)
-  Last login?
-
  Overall Stats:
   # of accounts
   # of calendars
   # of events
 
- Log Stats:
-  # Invitations sent per day/week/month
-  # bytes i/o
-  # requests
-  user agents
-
 """
 import os
 import xattr

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20061122/b38bd501/attachment.html


More information about the calendarserver-changes mailing list