rda-python-metrics 2.0.5__py3-none-any.whl → 3.0.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- rda_python_metrics/PgView.py +3 -3
- rda_python_metrics/__init__.py +28 -0
- rda_python_metrics/fill_awsusage.py +1 -1
- rda_python_metrics/fill_cdgusage.py +2 -2
- rda_python_metrics/fill_globususage.py +1 -1
- rda_python_metrics/fill_osdfusage.py +1 -1
- rda_python_metrics/fill_rdadb.py +1 -1
- rda_python_metrics/fill_tdsusage.py +1 -1
- rda_python_metrics/fillawsusage.py +11 -9
- rda_python_metrics/fillawsusage.usg +20 -9
- rda_python_metrics/fillcdgusage.py +17 -15
- rda_python_metrics/fillcdgusage.usg +25 -10
- rda_python_metrics/fillcodusage.py +11 -9
- rda_python_metrics/fillcodusage.usg +22 -11
- rda_python_metrics/fillcountry.py +8 -6
- rda_python_metrics/fillendtime.py +7 -5
- rda_python_metrics/fillgdexusage.py +972 -979
- rda_python_metrics/fillgdexusage.usg +25 -10
- rda_python_metrics/fillglobususage.py +14 -12
- rda_python_metrics/fillglobususage.usg +23 -11
- rda_python_metrics/fillipinfo.py +15 -15
- rda_python_metrics/fillipinfo.usg +29 -11
- rda_python_metrics/filloneorder.py +9 -7
- rda_python_metrics/filloneorder.usg +38 -40
- rda_python_metrics/fillosdfusage.py +11 -9
- rda_python_metrics/fillosdfusage.usg +20 -10
- rda_python_metrics/fillrdadb.py +9 -7
- rda_python_metrics/fillrdadb.usg +24 -20
- rda_python_metrics/filltdsusage.py +42 -39
- rda_python_metrics/filltdsusage.usg +20 -9
- rda_python_metrics/filluser.py +8 -6
- rda_python_metrics/filluser.usg +16 -8
- rda_python_metrics/fillzenodousage.py +382 -393
- rda_python_metrics/log_arch.py +2 -2
- rda_python_metrics/logarch.py +5 -2
- rda_python_metrics/logarch.usg +22 -17
- rda_python_metrics/pg_ipinfo.py +29 -28
- rda_python_metrics/pg_person.py +1 -1
- rda_python_metrics/pg_username.py +1 -1
- rda_python_metrics/pg_view.py +25 -30
- rda_python_metrics/pgperson.py +4 -4
- rda_python_metrics/pgsyspath.py +1 -1
- rda_python_metrics/pgusername.py +2 -2
- rda_python_metrics/view_allusage.py +9 -9
- rda_python_metrics/view_awsusage.py +13 -13
- rda_python_metrics/view_checkusage.py +10 -10
- rda_python_metrics/view_codusage.py +8 -8
- rda_python_metrics/view_ordusage.py +14 -14
- rda_python_metrics/view_osdfusage.py +13 -13
- rda_python_metrics/view_rqstusage.py +9 -9
- rda_python_metrics/view_tdsusage.py +13 -13
- rda_python_metrics/view_webfile.py +11 -13
- rda_python_metrics/view_webusage.py +11 -11
- rda_python_metrics/viewallusage.py +21 -16
- rda_python_metrics/viewallusage.usg +149 -214
- rda_python_metrics/viewawsusage.py +25 -20
- rda_python_metrics/viewawsusage.usg +122 -189
- rda_python_metrics/viewcheckusage.py +18 -17
- rda_python_metrics/viewcheckusage.usg +104 -158
- rda_python_metrics/viewcodusage.py +160 -155
- rda_python_metrics/viewcodusage.usg +122 -186
- rda_python_metrics/viewordusage.py +21 -20
- rda_python_metrics/viewordusage.usg +130 -222
- rda_python_metrics/viewosdfusage.py +27 -22
- rda_python_metrics/viewosdfusage.usg +122 -189
- rda_python_metrics/viewrqstusage.py +24 -19
- rda_python_metrics/viewrqstusage.usg +141 -216
- rda_python_metrics/viewtdsusage.py +25 -20
- rda_python_metrics/viewtdsusage.usg +126 -193
- rda_python_metrics/viewwebfile.py +17 -18
- rda_python_metrics/viewwebfile.usg +142 -211
- rda_python_metrics/viewwebusage.py +19 -18
- rda_python_metrics/viewwebusage.usg +140 -210
- rda_python_metrics-3.0.2.dist-info/METADATA +185 -0
- rda_python_metrics-3.0.2.dist-info/RECORD +86 -0
- {rda_python_metrics-2.0.5.dist-info → rda_python_metrics-3.0.2.dist-info}/WHEEL +1 -1
- {rda_python_metrics-2.0.5.dist-info → rda_python_metrics-3.0.2.dist-info}/entry_points.txt +1 -1
- rda_python_metrics-2.0.5.dist-info/METADATA +0 -23
- rda_python_metrics-2.0.5.dist-info/RECORD +0 -86
- {rda_python_metrics-2.0.5.dist-info → rda_python_metrics-3.0.2.dist-info}/licenses/LICENSE +0 -0
- {rda_python_metrics-2.0.5.dist-info → rda_python_metrics-3.0.2.dist-info}/top_level.txt +0 -0
rda_python_metrics/PgView.py
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
# Date : 09/24/2020
|
|
7
7
|
# 2025-03-27 transferred to package rda_python_metrics from
|
|
8
8
|
# https://github.com/NCAR/rda-database.git
|
|
9
|
-
# Purpose : python library module to help
|
|
9
|
+
# Purpose : python library module to help routinely updates of new data
|
|
10
10
|
# for one or multiple datasets
|
|
11
11
|
#
|
|
12
12
|
# Github : https://github.com/NCAR/rda-python-metrics.git
|
|
@@ -32,7 +32,7 @@ def simple_output(params, flds, records, totals = None):
|
|
|
32
32
|
sep = params['L'][0] if 'L' in params else ' '
|
|
33
33
|
slen = len(sep)
|
|
34
34
|
|
|
35
|
-
# get total line length, dynamically evaluating column
|
|
35
|
+
# get total line length, dynamically evaluating column lengths if column 4 in %FLDS is zero
|
|
36
36
|
rcnt = linelen = 0
|
|
37
37
|
if 'A' in params: rcnt = int(params['A'][0])
|
|
38
38
|
for i in range(ccnt):
|
|
@@ -390,7 +390,7 @@ def join_query_tables(tblname, tablenames = '', joins = '', tbljoin = ''):
|
|
|
390
390
|
return (tablenames, joins)
|
|
391
391
|
|
|
392
392
|
#
|
|
393
|
-
# expand
|
|
393
|
+
# expand records via query action
|
|
394
394
|
#
|
|
395
395
|
def expand_query(expid, records, params, expand, vusg = None, sns = None, flds = None):
|
|
396
396
|
|
rda_python_metrics/__init__.py
CHANGED
|
@@ -1 +1,29 @@
|
|
|
1
|
+
"""rda_python_metrics: RDA metrics, usage, and accounting utility package.
|
|
1
2
|
|
|
3
|
+
This package exposes two parallel APIs:
|
|
4
|
+
|
|
5
|
+
1. Legacy module-based API (back-compat). Import the capitalized
|
|
6
|
+
submodules and call their module-level functions, e.g.::
|
|
7
|
+
|
|
8
|
+
from rda_python_metrics import PgIPInfo, PgView
|
|
9
|
+
|
|
10
|
+
2. Class-based API (preferred for new code). Import the class from the
|
|
11
|
+
lower-case module and either instantiate or subclass it, e.g.::
|
|
12
|
+
|
|
13
|
+
from rda_python_metrics.pg_ipinfo import PgIPInfo
|
|
14
|
+
from rda_python_metrics.pg_view import PgView
|
|
15
|
+
|
|
16
|
+
The legacy submodules are eagerly imported below so that
|
|
17
|
+
``from rda_python_metrics import PgIPInfo`` continues to return the
|
|
18
|
+
module object that existing callers expect.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
from . import PgIPInfo, PgView
|
|
22
|
+
|
|
23
|
+
__version__ = "2.0.6"
|
|
24
|
+
|
|
25
|
+
__all__ = [
|
|
26
|
+
"PgIPInfo",
|
|
27
|
+
"PgView",
|
|
28
|
+
"__version__",
|
|
29
|
+
]
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
# Purpose : python program to retrieve info from AWS logs
|
|
11
11
|
# and fill table wusages in PgSQL database dssdb.
|
|
12
12
|
#
|
|
13
|
-
# Github : https://github.com/NCAR/rda-
|
|
13
|
+
# Github : https://github.com/NCAR/rda-python-metrics.git
|
|
14
14
|
#
|
|
15
15
|
###############################################################################
|
|
16
16
|
#
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
# Author : Zaihua Ji, zji@ucar.edu
|
|
7
7
|
# Date : 2025-04-14
|
|
8
8
|
# Purpose : python program to retrieve info from GDEX Postgres database for GDS
|
|
9
|
-
# file accesses and backup fill table tdsusage in PostgreSQL database
|
|
9
|
+
# file accesses and backup fill table tdsusage in PostgreSQL database rdadb.
|
|
10
10
|
#
|
|
11
11
|
# Github : https://github.com/NCAR/rda-python-metrics.git
|
|
12
12
|
#
|
|
@@ -173,7 +173,7 @@ def get_dataset_ids(dsnames):
|
|
|
173
173
|
return dsids
|
|
174
174
|
|
|
175
175
|
#
|
|
176
|
-
# get cdgids
|
|
176
|
+
# get cdgids recursively
|
|
177
177
|
#
|
|
178
178
|
def recursive_dataset_ids(pcdgid, cdgids):
|
|
179
179
|
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
# Purpose : python program to retrieve info from Globus logs
|
|
11
11
|
# and fill table wusages in PgSQL database dssdb.
|
|
12
12
|
#
|
|
13
|
-
# Github : https://github.com/NCAR/rda-
|
|
13
|
+
# Github : https://github.com/NCAR/rda-python-metrics.git
|
|
14
14
|
#
|
|
15
15
|
###############################################################################
|
|
16
16
|
#
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
# Purpose : python program to retrieve info from weekly OSDF logs
|
|
9
9
|
# and fill table wusages in PgSQL database dssdb.
|
|
10
10
|
#
|
|
11
|
-
# Github : https://github.com/NCAR/rda-
|
|
11
|
+
# Github : https://github.com/NCAR/rda-python-metrics.git
|
|
12
12
|
#
|
|
13
13
|
###############################################################################
|
|
14
14
|
#
|
rda_python_metrics/fill_rdadb.py
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
# Purpose : python program to retrieve info from data logs, and fill tables
|
|
11
11
|
# in PostgreSQL database.schema rdadb.dssdb
|
|
12
12
|
#
|
|
13
|
-
# Github : https://github.com/NCAR/rda-
|
|
13
|
+
# Github : https://github.com/NCAR/rda-python-metrics.git
|
|
14
14
|
#
|
|
15
15
|
###############################################################################
|
|
16
16
|
#
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
# 2025-03-26 transferred to package rda_python_metrics from
|
|
9
9
|
# https://github.com/NCAR/rda-database.git
|
|
10
10
|
# Purpose : python program to retrieve info from TDS logs
|
|
11
|
-
# and fill table tdsusage in PostgreSQL database
|
|
11
|
+
# and fill table tdsusage in PostgreSQL database rdadb.
|
|
12
12
|
#
|
|
13
13
|
# Github : https://github.com/NCAR/rda-python-metrics.git
|
|
14
14
|
#
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
# 2025-12-16 converted to class FillAWSUsage
|
|
9
9
|
# Purpose : python program to retrieve info from AWS logs
|
|
10
10
|
# and fill table wusages in PgSQL database dssdb.
|
|
11
|
-
# Github : https://github.com/NCAR/rda-
|
|
11
|
+
# Github : https://github.com/NCAR/rda-python-metrics.git
|
|
12
12
|
###############################################################################
|
|
13
13
|
import sys
|
|
14
14
|
import re
|
|
@@ -19,6 +19,8 @@ from .pg_ipinfo import PgIPInfo
|
|
|
19
19
|
|
|
20
20
|
class FillAWSUsage(PgIPInfo, PgFile):
|
|
21
21
|
|
|
22
|
+
"""Retrieve info from AWS logs and fill table wusage in PostgreSQL database rdadb."""
|
|
23
|
+
|
|
22
24
|
def __init__(self):
|
|
23
25
|
super().__init__()
|
|
24
26
|
self.USAGE = {
|
|
@@ -31,8 +33,8 @@ class FillAWSUsage(PgIPInfo, PgFile):
|
|
|
31
33
|
self.option = self.cmdstr = None
|
|
32
34
|
self.params = [] # array of input values
|
|
33
35
|
|
|
34
|
-
# function to read parameters
|
|
35
36
|
def read_parameters(self):
|
|
37
|
+
"""Function to read parameters."""
|
|
36
38
|
argv = sys.argv[1:]
|
|
37
39
|
for arg in argv:
|
|
38
40
|
ms = re.match(r'^-(b|d|p|N)$', arg)
|
|
@@ -55,8 +57,8 @@ class FillAWSUsage(PgIPInfo, PgFile):
|
|
|
55
57
|
self.cmdstr = "fillawsusage {}".format(' '.join(argv))
|
|
56
58
|
self.cmdlog(self.cmdstr)
|
|
57
59
|
|
|
58
|
-
# function to start actions
|
|
59
60
|
def start_actions(self):
|
|
61
|
+
"""Function to start actions."""
|
|
60
62
|
self.change_local_directory(self.USAGE['AWSDIR'])
|
|
61
63
|
filenames = self.get_log_file_names()
|
|
62
64
|
if filenames:
|
|
@@ -65,8 +67,8 @@ class FillAWSUsage(PgIPInfo, PgFile):
|
|
|
65
67
|
self.pglog("No log file found for given command: " + self.cmdstr, self.LOGWRN)
|
|
66
68
|
self.pglog(None, self.LOGWRN)
|
|
67
69
|
|
|
68
|
-
# get the log file dates
|
|
69
70
|
def get_log_file_names(self):
|
|
71
|
+
"""Get the log file dates."""
|
|
70
72
|
filenames = {}
|
|
71
73
|
if self.option == 'd':
|
|
72
74
|
for dt in self.params:
|
|
@@ -93,8 +95,8 @@ class FillAWSUsage(PgIPInfo, PgFile):
|
|
|
93
95
|
pdate = self.adddate(pdate, 0, 0, 1)
|
|
94
96
|
return filenames
|
|
95
97
|
|
|
96
|
-
# Fill AWS usages into table dssdb.awsusage of DSS PgSQL database from aws access logs
|
|
97
98
|
def fill_aws_usages(self, filenames):
|
|
99
|
+
"""Fill AWS usages into table dssdb.awsusage of DSS PgSQL database from aws access logs."""
|
|
98
100
|
year = cntall = addall = 0
|
|
99
101
|
for pdate in filenames:
|
|
100
102
|
fnames = filenames[pdate]
|
|
@@ -147,8 +149,8 @@ class FillAWSUsage(PgIPInfo, PgFile):
|
|
|
147
149
|
if addall > cntadd:
|
|
148
150
|
self.pglog("{} AWS usage records added for {} entries at {}".format(addall, cntall, self.current_datetime()), self.LOGWRN)
|
|
149
151
|
|
|
150
|
-
# get date and time from record
|
|
151
152
|
def get_record_date_time(self, ctime):
|
|
153
|
+
"""Get date and time from record."""
|
|
152
154
|
ms = re.search(r'^(\d+)/(\w+)/(\d+):(\d+:\d+:\d+)$', ctime)
|
|
153
155
|
if ms:
|
|
154
156
|
d = int(ms.group(1))
|
|
@@ -160,8 +162,8 @@ class FillAWSUsage(PgIPInfo, PgFile):
|
|
|
160
162
|
else:
|
|
161
163
|
self.pglog(ctime + ": Invalid date/time format", self.LGEREX)
|
|
162
164
|
|
|
163
|
-
# add usage records for year
|
|
164
165
|
def add_usage_records(self, records, year):
|
|
166
|
+
"""Add usage records for year."""
|
|
165
167
|
cnt = 0
|
|
166
168
|
for key in records:
|
|
167
169
|
record = records[key]
|
|
@@ -171,8 +173,8 @@ class FillAWSUsage(PgIPInfo, PgFile):
|
|
|
171
173
|
cnt += self.pgadd(self.USAGE['PGTBL'], record, self.LOGWRN)
|
|
172
174
|
return cnt
|
|
173
175
|
|
|
174
|
-
# add record to allusage tables
|
|
175
176
|
def add_to_allusage(self, year, pgrec):
|
|
177
|
+
"""Add record to allusage tables."""
|
|
176
178
|
record = {'source' : 'A'}
|
|
177
179
|
flds = ['ip', 'dsid', 'date', 'time', 'quarter', 'size', 'method',
|
|
178
180
|
'org_type', 'country', 'region', 'email']
|
|
@@ -180,7 +182,7 @@ class FillAWSUsage(PgIPInfo, PgFile):
|
|
|
180
182
|
record[fld] = pgrec[fld]
|
|
181
183
|
return self.add_yearly_allusage(year, record)
|
|
182
184
|
|
|
183
|
-
# main function to
|
|
185
|
+
# main function to execute this script
|
|
184
186
|
def main():
|
|
185
187
|
object = FillAWSUsage()
|
|
186
188
|
object.read_parameters()
|
|
@@ -1,16 +1,27 @@
|
|
|
1
1
|
|
|
2
|
-
|
|
3
|
-
../rda/transer/AWSera5log/ to fill table 'awsusage' in database 'rdadb'.
|
|
2
|
+
fillawsusage - Fill table 'awsusage' from AWS Server log files.
|
|
4
3
|
|
|
5
|
-
|
|
4
|
+
Reads AWS access logs from /gpfs/fs1/collections/rda/transer/AWSera5log/
|
|
5
|
+
and inserts usage records into the 'awsusage' table in PostgreSQL
|
|
6
|
+
database 'rdadb'.
|
|
6
7
|
|
|
7
|
-
|
|
8
|
+
USAGE:
|
|
9
|
+
fillawsusage [-b] (-d LogFileDates | -N NumberDays | -p BeginDate [EndDate])
|
|
8
10
|
|
|
9
|
-
|
|
11
|
+
OPTIONS (choose exactly one of -d, -N, or -p):
|
|
10
12
|
|
|
11
|
-
|
|
13
|
+
-d LogFileDates
|
|
14
|
+
Process log files for the given dates.
|
|
15
|
+
Date format: YYYY-MM-DD (e.g. 2024-01-15).
|
|
12
16
|
|
|
13
|
-
|
|
17
|
+
-N NumberDays
|
|
18
|
+
Process log files covering the most recent NumberDays days.
|
|
14
19
|
|
|
15
|
-
|
|
16
|
-
|
|
20
|
+
-p BeginDate [EndDate]
|
|
21
|
+
Process log files between BeginDate and EndDate, inclusive.
|
|
22
|
+
EndDate defaults to today if omitted.
|
|
23
|
+
|
|
24
|
+
-b Run in background mode (log to file only, no terminal output).
|
|
25
|
+
|
|
26
|
+
EXAMPLE:
|
|
27
|
+
fillawsusage -p 2024-01-01 2024-01-31
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
# Date : 2025-04-14
|
|
6
6
|
# 2025-12-16 convert to class FillCDGUsage
|
|
7
7
|
# Purpose : python program to retrieve info from GDEX Postgres database for GDS
|
|
8
|
-
# file accesses and backup fill table tdsusage in PostgreSQL database
|
|
8
|
+
# file accesses and backup fill table tdsusage in PostgreSQL database rdadb.
|
|
9
9
|
# Github : https://github.com/NCAR/rda-python-metrics.git
|
|
10
10
|
###############################################################################
|
|
11
11
|
import sys
|
|
@@ -18,6 +18,8 @@ from .pg_ipinfo import PgIPInfo
|
|
|
18
18
|
|
|
19
19
|
class FillCDGUsage(PgSplit, PgIPInfo):
|
|
20
20
|
|
|
21
|
+
"""Retrieve info from GDEX Postgres database for CDG file accesses and fill tables tdsusage and wusage in PostgreSQL database rdadb."""
|
|
22
|
+
|
|
21
23
|
def __init__(self):
|
|
22
24
|
super().__init__()
|
|
23
25
|
self.USAGE = {
|
|
@@ -92,8 +94,8 @@ class FillCDGUsage(PgSplit, PgIPInfo):
|
|
|
92
94
|
self.WFILES = {}
|
|
93
95
|
self.params = {} # array of input values
|
|
94
96
|
|
|
95
|
-
# function to run this program
|
|
96
97
|
def read_parameters(self):
|
|
98
|
+
"""Function to run this program."""
|
|
97
99
|
argv = sys.argv[1:]
|
|
98
100
|
opt = None
|
|
99
101
|
for arg in argv:
|
|
@@ -116,19 +118,19 @@ class FillCDGUsage(PgSplit, PgIPInfo):
|
|
|
116
118
|
self.pglog("-(m|N|y): Missing Month, NumberDays or Year to gather CDG metrics", self.LGWNEX)
|
|
117
119
|
self.cmdlog("fillcdgusage {}".format(' '.join(argv)))
|
|
118
120
|
|
|
119
|
-
# function to start actions
|
|
120
121
|
def start_actions(self):
|
|
122
|
+
"""Function to start actions."""
|
|
121
123
|
dranges = self.get_date_ranges(self.params)
|
|
122
124
|
dsids = self.get_dataset_ids(self.params['s'])
|
|
123
125
|
if dranges and dsids: self.fill_cdg_usages(dsids, dranges)
|
|
124
126
|
self.pglog(None, self.LOGWRN|self.SNDEML) # send email out if any
|
|
125
127
|
|
|
126
|
-
# connect to the gdex database esg-production
|
|
127
128
|
def gdex_dbname(self):
|
|
129
|
+
"""Connect to the gdex database esg-production."""
|
|
128
130
|
self.set_scname('esg-production', 'metrics', 'gateway-reader', None, 'sagedbprodalma.ucar.edu')
|
|
129
131
|
|
|
130
|
-
# get datasets
|
|
131
132
|
def get_dataset_ids(self, dsnames):
|
|
133
|
+
"""Get datasets."""
|
|
132
134
|
self.gdex_dbname()
|
|
133
135
|
dsids = []
|
|
134
136
|
tbname = 'metadata.dataset'
|
|
@@ -152,8 +154,8 @@ class FillCDGUsage(PgSplit, PgIPInfo):
|
|
|
152
154
|
if not dsids: self.pglog("No Dataset Id identified to gather CDG metrics", self.LOGWRN)
|
|
153
155
|
return dsids
|
|
154
156
|
|
|
155
|
-
# get cdgids recursivley
|
|
156
157
|
def recursive_dataset_ids(self, pcdgid, cdgids):
|
|
158
|
+
"""Get cdgids recursively."""
|
|
157
159
|
tbname = 'metadata.dataset'
|
|
158
160
|
pgrecs = self.pgmget(tbname, 'id', "parent_dataset_id = '{}'".format(pcdgid))
|
|
159
161
|
if not pgrecs: return 0
|
|
@@ -165,8 +167,8 @@ class FillCDGUsage(PgSplit, PgIPInfo):
|
|
|
165
167
|
ccnt += self.recursive_dataset_ids(cdgid, cdgids)
|
|
166
168
|
return ccnt
|
|
167
169
|
|
|
168
|
-
# get the date ranges for given condition
|
|
169
170
|
def get_date_ranges(self, inputs):
|
|
171
|
+
"""Get the date ranges for given condition."""
|
|
170
172
|
dranges = []
|
|
171
173
|
for opt in inputs:
|
|
172
174
|
for input in inputs[opt]:
|
|
@@ -185,8 +187,8 @@ class FillCDGUsage(PgSplit, PgIPInfo):
|
|
|
185
187
|
if dates: dranges.append(dates)
|
|
186
188
|
return dranges
|
|
187
189
|
|
|
188
|
-
# get file download records for given dsid
|
|
189
190
|
def get_dsid_records(self, cdgids, dates, strids):
|
|
191
|
+
"""Get file download records for given dsid."""
|
|
190
192
|
self.gdex_dbname()
|
|
191
193
|
tbname = 'metrics.file_download'
|
|
192
194
|
fields = ('date_completed, remote_address, logical_file_size, logical_file_name, file_access_point_uri, user_agent_name, bytes_sent, '
|
|
@@ -204,8 +206,8 @@ class FillCDGUsage(PgSplit, PgIPInfo):
|
|
|
204
206
|
self.dssdb_dbname()
|
|
205
207
|
return pgrecs
|
|
206
208
|
|
|
207
|
-
# Fill TDS usages into table dssdb.tdsusage from cdg access records
|
|
208
209
|
def fill_cdg_usages(self, dsids, dranges):
|
|
210
|
+
"""Fill TDS usages into table dssdb.tdsusage from cdg access records."""
|
|
209
211
|
allcnt = awcnt = atcnt = lcnt = 0
|
|
210
212
|
for dates in dranges:
|
|
211
213
|
for adsid in dsids:
|
|
@@ -305,8 +307,8 @@ class FillCDGUsage(PgSplit, PgIPInfo):
|
|
|
305
307
|
rmsg = self.seconds_to_string_time(tm() - bt)
|
|
306
308
|
self.pglog("{}: {}/{} TDS/WEB usage records added for {} CDG entries in {}".format(strids, atcnt, awcnt, allcnt, rmsg), self.LOGWRN)
|
|
307
309
|
|
|
308
|
-
# get date and time from log record
|
|
309
310
|
def get_record_date_time(self, ctime):
|
|
311
|
+
"""Get date and time from log record."""
|
|
310
312
|
ms = re.search(r'^(\d+)-(\d+)-(\d+) (\d\d:\d\d:\d\d)', str(ctime))
|
|
311
313
|
if ms:
|
|
312
314
|
y = ms.group(1)
|
|
@@ -318,8 +320,8 @@ class FillCDGUsage(PgSplit, PgIPInfo):
|
|
|
318
320
|
else:
|
|
319
321
|
self.pglog(str(ctime) + ": Invalid time format", self.LGEREX)
|
|
320
322
|
|
|
321
|
-
# add to tds usage records
|
|
322
323
|
def add_tdsusage_records(self, year, records, date):
|
|
324
|
+
"""Add to tds usage records."""
|
|
323
325
|
cnt = 0
|
|
324
326
|
for key in records:
|
|
325
327
|
record = records[key]
|
|
@@ -345,8 +347,8 @@ class FillCDGUsage(PgSplit, PgIPInfo):
|
|
|
345
347
|
pgrec['ip'] = logrec['ip']
|
|
346
348
|
return self.add_yearly_allusage(year, pgrec)
|
|
347
349
|
|
|
348
|
-
# Fill usage of a single online data file into table dssdb.wusage of DSS PgSQL database
|
|
349
350
|
def add_webfile_usage(self, year, logrec):
|
|
351
|
+
"""Fill usage of a single online data file into table dssdb.wusage of DSS PgSQL database."""
|
|
350
352
|
table = "{}_{}".format(self.USAGE['WEBTBL'], year)
|
|
351
353
|
cdate = logrec['date']
|
|
352
354
|
ip = logrec['ip']
|
|
@@ -368,8 +370,8 @@ class FillCDGUsage(PgSplit, PgIPInfo):
|
|
|
368
370
|
else:
|
|
369
371
|
return 0
|
|
370
372
|
|
|
371
|
-
# add web record to allusage
|
|
372
373
|
def add_web_allusage(self, year, logrec, wurec):
|
|
374
|
+
"""Add web record to allusage."""
|
|
373
375
|
pgrec = {'source' : 'C'}
|
|
374
376
|
pgrec['email'] = wurec['email']
|
|
375
377
|
pgrec['org_type'] = wurec['org_type']
|
|
@@ -384,8 +386,8 @@ class FillCDGUsage(PgSplit, PgIPInfo):
|
|
|
384
386
|
pgrec['ip'] = logrec['ip']
|
|
385
387
|
return self.add_yearly_allusage(year, pgrec)
|
|
386
388
|
|
|
387
|
-
# return wfile.wid upon success, 0 otherwise
|
|
388
389
|
def get_wfile_record(self, dsids, wfile):
|
|
390
|
+
"""Return wfile.wid upon success, 0 otherwise."""
|
|
389
391
|
for dsid in dsids:
|
|
390
392
|
wkey = "{}{}".format(dsid, wfile)
|
|
391
393
|
if wkey in self.WFILES: return self.WFILES[wkey]
|
|
@@ -410,7 +412,7 @@ class FillCDGUsage(PgSplit, PgIPInfo):
|
|
|
410
412
|
self.WFILES[wkey] = pgrec
|
|
411
413
|
return pgrec
|
|
412
414
|
|
|
413
|
-
# main function to
|
|
415
|
+
# main function to execute this script
|
|
414
416
|
def main():
|
|
415
417
|
object = FillCDGUsage()
|
|
416
418
|
object.read_parameters()
|
|
@@ -1,18 +1,33 @@
|
|
|
1
1
|
|
|
2
|
-
|
|
3
|
-
fill table 'tdsusage' and 'webusage' in PostgreSQL database 'rdadb'.
|
|
2
|
+
fillcdgusage - Fill table 'tdsusage' and 'webusage' from CDG GDEX metrics.
|
|
4
3
|
|
|
5
|
-
|
|
4
|
+
Retrieves CDG (Climate Data Gateway) usage info from the GDEX metrics
|
|
5
|
+
database and inserts records into the 'tdsusage' and 'webusage' tables
|
|
6
|
+
in PostgreSQL database 'rdadb'.
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
|
|
8
|
+
USAGE:
|
|
9
|
+
fillcdgusage [-b] -s DatasetShortNames
|
|
10
|
+
(-m MonthList | -N NumberDays | -y YearList)
|
|
9
11
|
|
|
10
|
-
|
|
12
|
+
OPTIONS:
|
|
11
13
|
|
|
12
|
-
|
|
14
|
+
-s DatasetShortNames (required)
|
|
15
|
+
Gather usage info for the given dataset short names.
|
|
13
16
|
|
|
14
|
-
|
|
17
|
+
One of the following time-range options is required:
|
|
15
18
|
|
|
16
|
-
|
|
19
|
+
-m MonthList
|
|
20
|
+
Gather usage info for the given months.
|
|
21
|
+
Month format: YYYY-MM (e.g. 2024-01).
|
|
17
22
|
|
|
18
|
-
|
|
23
|
+
-N NumberDays
|
|
24
|
+
Gather usage info for the most recent NumberDays days.
|
|
25
|
+
|
|
26
|
+
-y YearList
|
|
27
|
+
Gather usage info for the given years.
|
|
28
|
+
Year format: YYYY (e.g. 2024).
|
|
29
|
+
|
|
30
|
+
-b Run in background mode (log to file only, no terminal output).
|
|
31
|
+
|
|
32
|
+
EXAMPLE:
|
|
33
|
+
fillcdgusage -s ds083.2 -y 2024
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
# https://github.com/NCAR/rda-database.git
|
|
8
8
|
# 2025-12-17 convert to class FillCODEUsage
|
|
9
9
|
# Purpose : python program to retrieve info from web logs
|
|
10
|
-
# and fill table codusage in PostgreSQL database
|
|
10
|
+
# and fill table codusage in PostgreSQL database rdadb.
|
|
11
11
|
# Github : https://github.com/NCAR/rda-python-metrics.git
|
|
12
12
|
###############################################################################
|
|
13
13
|
import sys
|
|
@@ -18,6 +18,8 @@ from .pg_ipinfo import PgIPInfo
|
|
|
18
18
|
|
|
19
19
|
class FillCODUsage(PgIPInfo):
|
|
20
20
|
|
|
21
|
+
"""Retrieve info from web logs and fill table codusage in PostgreSQL database rdadb."""
|
|
22
|
+
|
|
21
23
|
def __init__(self):
|
|
22
24
|
super().__init__()
|
|
23
25
|
# the define options for gathering COD data usage, one at a time
|
|
@@ -36,8 +38,8 @@ class FillCODUsage(PgIPInfo):
|
|
|
36
38
|
self.datelimit = ''
|
|
37
39
|
self.params = [] # array of input values
|
|
38
40
|
|
|
39
|
-
# function to readparameters
|
|
40
41
|
def read_parameters(self):
|
|
42
|
+
"""Function to readparameters."""
|
|
41
43
|
argv = sys.argv[1:]
|
|
42
44
|
for arg in argv:
|
|
43
45
|
if arg == "-b":
|
|
@@ -64,8 +66,8 @@ class FillCODUsage(PgIPInfo):
|
|
|
64
66
|
self.dssdb_dbname()
|
|
65
67
|
self.cmdlog("fillcodusage {}".format(' '.join(argv)))
|
|
66
68
|
|
|
67
|
-
# function to start actions
|
|
68
69
|
def start_actions(self):
|
|
70
|
+
"""Function to start actions."""
|
|
69
71
|
if self.USAGE['OPTION']&self.NDAYS:
|
|
70
72
|
curdate = self.curdate()
|
|
71
73
|
self.datelimit = self.adddate(curdate, 0, 0, -int(self.params[0]))
|
|
@@ -78,8 +80,8 @@ class FillCODUsage(PgIPInfo):
|
|
|
78
80
|
self.fill_cod_usages(self.USAGE['OPTION'], self.params)
|
|
79
81
|
self.pglog(None, self.LOGWRN|self.SNDEML) # send email out if any
|
|
80
82
|
|
|
81
|
-
# Fill COD usages into table dssdb.codusage of DSS PostgreSQL database from cod access logs
|
|
82
83
|
def fill_cod_usages(self, option, inputs):
|
|
84
|
+
"""Fill COD usages into table dssdb.codusage of DSS PostgreSQL database from cod access logs."""
|
|
83
85
|
cntall = cntadd = 0
|
|
84
86
|
for input in inputs:
|
|
85
87
|
# get log file names
|
|
@@ -144,8 +146,8 @@ class FillCODUsage(PgIPInfo):
|
|
|
144
146
|
s = 's' if cntadd > 1 else ''
|
|
145
147
|
self.pglog("{} COD usage records added for {} entries at {}".format(cntadd, cntall, self.current_datetime()), self.LOGWRN)
|
|
146
148
|
|
|
147
|
-
# add usage to codusage table
|
|
148
149
|
def add_usage_records(self, records, date):
|
|
150
|
+
"""Add usage to codusage table."""
|
|
149
151
|
ms = re.match(r'(\d+)-(\d+)-', date)
|
|
150
152
|
if not ms: return 0
|
|
151
153
|
year = ms.group(1)
|
|
@@ -178,8 +180,8 @@ class FillCODUsage(PgIPInfo):
|
|
|
178
180
|
cnt += self.pgadd(self.USAGE['PGTBL'], record, self.LOGWRN)
|
|
179
181
|
return cnt
|
|
180
182
|
|
|
181
|
-
# add usage to allusage tables
|
|
182
183
|
def add_to_allusage(self, pgrec, year):
|
|
184
|
+
"""Add usage to allusage tables."""
|
|
183
185
|
record = {'method' : 'COD', 'source' : 'C'}
|
|
184
186
|
for fld in pgrec:
|
|
185
187
|
ms = re.match(r'^(engine|count)$', fld)
|
|
@@ -187,8 +189,8 @@ class FillCODUsage(PgIPInfo):
|
|
|
187
189
|
record[fld] = pgrec[fld]
|
|
188
190
|
return self.add_yearly_allusage(year, record) # change 1 to 0 to stop checking
|
|
189
191
|
|
|
190
|
-
# cashe user info for reuse
|
|
191
192
|
def cache_users(self, aid):
|
|
193
|
+
"""Cashe user info for reuse."""
|
|
192
194
|
pgrec = self.pgget("metautil.custom_dap_history", "*", "ID = '{}'".format(aid), self.LGEREX)
|
|
193
195
|
if pgrec:
|
|
194
196
|
ms = re.search(r'dsnum=(\d+\.\d|[a-z]\d{6});', pgrec['rinfo'])
|
|
@@ -198,8 +200,8 @@ class FillCODUsage(PgIPInfo):
|
|
|
198
200
|
return 1
|
|
199
201
|
return 0
|
|
200
202
|
|
|
201
|
-
# get period
|
|
202
203
|
def access_period(self, etime, btime):
|
|
204
|
+
"""Get period."""
|
|
203
205
|
period = 86400
|
|
204
206
|
ms = re.search(r'(\d+):(\d+):(\d+)', etime)
|
|
205
207
|
if ms:
|
|
@@ -209,7 +211,7 @@ class FillCODUsage(PgIPInfo):
|
|
|
209
211
|
period -= int(ms.group(1))*3600+int(ms.group(2))*60+int(ms.group(3))
|
|
210
212
|
return period
|
|
211
213
|
|
|
212
|
-
# main function to
|
|
214
|
+
# main function to execute this script
|
|
213
215
|
def main():
|
|
214
216
|
object = FillCODUsage()
|
|
215
217
|
object.read_parameters()
|
|
@@ -1,21 +1,32 @@
|
|
|
1
1
|
|
|
2
|
-
|
|
3
|
-
fill table 'codusage' in database 'rdadb'.
|
|
2
|
+
fillcodusage - Fill table 'codusage' from custom OPeNDAP (COD) access logs.
|
|
4
3
|
|
|
5
|
-
|
|
4
|
+
Reads RDA Web/COD access logs under /var/log and inserts usage records
|
|
5
|
+
into the 'codusage' table in PostgreSQL database 'rdadb'.
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
USAGE:
|
|
8
|
+
fillcodusage [-b] (-a | -f LogFileNames | -m MonthList |
|
|
9
|
+
-N NumberDays | -y YearList)
|
|
9
10
|
|
|
10
|
-
|
|
11
|
+
OPTIONS (choose exactly one of -a, -f, -m, -N, or -y):
|
|
11
12
|
|
|
12
|
-
|
|
13
|
+
-a Process all available log files.
|
|
13
14
|
|
|
14
|
-
|
|
15
|
+
-f LogFileNames
|
|
16
|
+
Process the given log file names directly.
|
|
15
17
|
|
|
16
|
-
|
|
18
|
+
-m MonthList
|
|
19
|
+
Process log files for the given months.
|
|
20
|
+
Month format: YYYY-MM (e.g. 2024-01).
|
|
17
21
|
|
|
18
|
-
|
|
22
|
+
-N NumberDays
|
|
23
|
+
Process log files covering the most recent NumberDays days.
|
|
19
24
|
|
|
20
|
-
|
|
25
|
+
-y YearList
|
|
26
|
+
Process log files for the given years.
|
|
27
|
+
Year format: YYYY (e.g. 2024).
|
|
21
28
|
|
|
29
|
+
-b Run in background mode (log to file only, no terminal output).
|
|
30
|
+
|
|
31
|
+
EXAMPLE:
|
|
32
|
+
fillcodusage -m 2024-01 2024-02
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
2
|
###############################################################################
|
|
3
3
|
# Title : fillcountry
|
|
4
4
|
# Author : Zaihua Ji, zji@ucar.edu
|
|
@@ -15,13 +15,15 @@ import re
|
|
|
15
15
|
from rda_python_common.pg_dbi import PgDBI
|
|
16
16
|
|
|
17
17
|
class FillCountry(PgDBI):
|
|
18
|
+
"""Fill missing country field from email info for a given table name."""
|
|
19
|
+
|
|
18
20
|
def __init__(self):
|
|
19
21
|
super().__init__()
|
|
20
22
|
self.tables = ['allusage', 'user', 'wuser']
|
|
21
23
|
self.table = None
|
|
22
24
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
+
def read_parameters(self):
|
|
26
|
+
"""Function to read parameters."""
|
|
25
27
|
argv = sys.argv[1:]
|
|
26
28
|
# check command line
|
|
27
29
|
for arg in argv:
|
|
@@ -40,13 +42,13 @@ class FillCountry(PgDBI):
|
|
|
40
42
|
self.pglog("{}: table name must be ({})".format(self.table, '|'.join(self.tables)), self.LGEREX)
|
|
41
43
|
self.cmdlog("fillcountry {}".format(' '.join(argv)))
|
|
42
44
|
|
|
43
|
-
# function to start actions
|
|
44
45
|
def start_actions(self):
|
|
46
|
+
"""Function to start actions."""
|
|
45
47
|
self.dssdb_dbname()
|
|
46
48
|
self.process_countries()
|
|
47
49
|
|
|
48
|
-
# fill country info
|
|
49
50
|
def process_countries(self):
|
|
51
|
+
"""Fill country info."""
|
|
50
52
|
pgrecs = self.pgmget(self.table, "email", "country IS NULL", self.LOGWRN)
|
|
51
53
|
cntall = len(pgrecs['email']) if pgrecs else 0
|
|
52
54
|
self.pglog("Set {} record(s) for missing country in table {}".format(cntall, self.table), self.LOGWRN)
|
|
@@ -60,7 +62,7 @@ class FillCountry(PgDBI):
|
|
|
60
62
|
cntmod += self.pgupdt(self.table, record, "email = '{}' AND country IS NULL".format(email), self.LOGWRN)
|
|
61
63
|
self.pglog("{} Record(s) modified in table '{}'".format(cntmod, self.table), self.LOGWRN)
|
|
62
64
|
|
|
63
|
-
# main function to
|
|
65
|
+
# main function to execute this script
|
|
64
66
|
def main():
|
|
65
67
|
object = FillCountry()
|
|
66
68
|
object.read_parameters()
|