rda-python-metrics 1.0.4__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.
Potentially problematic release.
This version of rda-python-metrics might be problematic. Click here for more details.
- rda_python_metrics/PgIPInfo.py +188 -0
- rda_python_metrics/PgView.py +782 -0
- rda_python_metrics/__init__.py +1 -0
- rda_python_metrics/fillawsusage.py +282 -0
- rda_python_metrics/fillawsusage.usg +17 -0
- rda_python_metrics/fillcodusage.py +247 -0
- rda_python_metrics/fillcodusage.usg +21 -0
- rda_python_metrics/fillcountry.py +79 -0
- rda_python_metrics/fillendtime.py +93 -0
- rda_python_metrics/fillglobususage.py +287 -0
- rda_python_metrics/fillglobususage.usg +17 -0
- rda_python_metrics/fillipinfo.py +185 -0
- rda_python_metrics/fillipinfo.usg +18 -0
- rda_python_metrics/filloneorder.py +155 -0
- rda_python_metrics/filloneorder.usg +41 -0
- rda_python_metrics/fillrdadb.py +151 -0
- rda_python_metrics/fillrdadb.usg +32 -0
- rda_python_metrics/filltdsusage.py +289 -0
- rda_python_metrics/filltdsusage.usg +17 -0
- rda_python_metrics/filluser.py +216 -0
- rda_python_metrics/filluser.usg +16 -0
- rda_python_metrics/logarch.py +359 -0
- rda_python_metrics/logarch.usg +27 -0
- rda_python_metrics/pgperson.py +72 -0
- rda_python_metrics/pgusername.py +50 -0
- rda_python_metrics/viewallusage.py +350 -0
- rda_python_metrics/viewallusage.usg +198 -0
- rda_python_metrics/viewcheckusage.py +289 -0
- rda_python_metrics/viewcheckusage.usg +185 -0
- rda_python_metrics/viewcodusage.py +314 -0
- rda_python_metrics/viewcodusage.usg +184 -0
- rda_python_metrics/viewordusage.py +340 -0
- rda_python_metrics/viewordusage.usg +224 -0
- rda_python_metrics/viewrqstusage.py +362 -0
- rda_python_metrics/viewrqstusage.usg +217 -0
- rda_python_metrics/viewtdsusage.py +323 -0
- rda_python_metrics/viewtdsusage.usg +191 -0
- rda_python_metrics/viewwebfile.py +294 -0
- rda_python_metrics/viewwebfile.usg +212 -0
- rda_python_metrics/viewwebusage.py +371 -0
- rda_python_metrics/viewwebusage.usg +211 -0
- rda_python_metrics-1.0.4.dist-info/METADATA +18 -0
- rda_python_metrics-1.0.4.dist-info/RECORD +47 -0
- rda_python_metrics-1.0.4.dist-info/WHEEL +5 -0
- rda_python_metrics-1.0.4.dist-info/entry_points.txt +22 -0
- rda_python_metrics-1.0.4.dist-info/licenses/LICENSE +21 -0
- rda_python_metrics-1.0.4.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
#
|
|
3
|
+
###############################################################################
|
|
4
|
+
#
|
|
5
|
+
# Title : filluser
|
|
6
|
+
# Author : Zaihua Ji, zji@ucar.edu
|
|
7
|
+
# Date : 02/15/2024
|
|
8
|
+
# 2025-03-26 transferred to package rda_python_metrics from
|
|
9
|
+
# https://github.com/NCAR/rda-database.git
|
|
10
|
+
# Purpose : python functions to retrieve info from Oracle database and fill
|
|
11
|
+
# table user in PostgreSQL database.schema rdadb.dssdb.
|
|
12
|
+
#
|
|
13
|
+
# Github : https://github.com/NCAR/rda-python-metrics.git
|
|
14
|
+
#
|
|
15
|
+
###############################################################################
|
|
16
|
+
import sys
|
|
17
|
+
import re
|
|
18
|
+
import time
|
|
19
|
+
from os import path as op
|
|
20
|
+
from rda_python_common import PgLOG
|
|
21
|
+
from rda_python_common import PgUtil
|
|
22
|
+
from rda_python_common import PgDBI
|
|
23
|
+
|
|
24
|
+
TBNAME = 'dssdb.user'
|
|
25
|
+
|
|
26
|
+
#
|
|
27
|
+
# main function to run this program
|
|
28
|
+
#
|
|
29
|
+
def main():
|
|
30
|
+
|
|
31
|
+
argv = sys.argv[1:]
|
|
32
|
+
missed = False
|
|
33
|
+
userno = logname = option = None
|
|
34
|
+
|
|
35
|
+
for arg in argv:
|
|
36
|
+
if arg == "-b":
|
|
37
|
+
PgLOG.PGLOG['BCKGRND'] = 1
|
|
38
|
+
elif re.match(r'^-[inu]$', arg):
|
|
39
|
+
option = arg[1]
|
|
40
|
+
if option == 'i':
|
|
41
|
+
missed = True
|
|
42
|
+
option = None
|
|
43
|
+
elif arg[0] == '-':
|
|
44
|
+
PgLOG.pglog(arg + ": Invalid Option", PgLOG.LGWNEX)
|
|
45
|
+
elif option == "n":
|
|
46
|
+
userno = arg
|
|
47
|
+
option = None
|
|
48
|
+
elif option == "u":
|
|
49
|
+
logname = arg
|
|
50
|
+
option = None
|
|
51
|
+
else:
|
|
52
|
+
PgLOG.pglog(arg + ": Invalid Parameter", PgLOG.LGWNEX)
|
|
53
|
+
|
|
54
|
+
if not (missed or userno or logname): PgLOG.show_usage('filluser')
|
|
55
|
+
|
|
56
|
+
if not PgLOG.valid_command("pgperson"):
|
|
57
|
+
errmsg = PgLOG.PGLOG['SYSERR'] if PgLOG.PGLOG['SYSERR'] else "Cannot find command"
|
|
58
|
+
PgLOG.pglog("filluser: Cannot be executed on '{}'\n{}".format(PgLOG.PGLOG['HOSTNAME'], errmsg), PgLOG.LGWNEX)
|
|
59
|
+
|
|
60
|
+
PgDBI.dssdb_scname()
|
|
61
|
+
PgLOG.cmdlog("filluser {}".format(' '.join(argv)))
|
|
62
|
+
if missed: # checking and fill missed ones in user table
|
|
63
|
+
fill_missed_users()
|
|
64
|
+
else:
|
|
65
|
+
fill_one_user(userno, logname)
|
|
66
|
+
|
|
67
|
+
sys.exit(0)
|
|
68
|
+
|
|
69
|
+
#
|
|
70
|
+
# update users with missed info in table dssdb.user
|
|
71
|
+
#
|
|
72
|
+
def fill_missed_users():
|
|
73
|
+
|
|
74
|
+
PgLOG.pglog("Getting incomplete user info", PgLOG.LOGWRN)
|
|
75
|
+
pgusers = PgDBI.pgmget(TBNAME, "*", "stat_flag = 'M'", PgLOG.LOGWRN)
|
|
76
|
+
cntall = len(pgusers['logname']) if pgusers else 0
|
|
77
|
+
s = 's' if cntall > 1 else ''
|
|
78
|
+
PgLOG.pglog("{} record{} retrieved at {}".format(cntall, s, PgLOG.current_datetime()), PgLOG.LOGWRN)
|
|
79
|
+
if not cntall: return
|
|
80
|
+
modcnt = 0
|
|
81
|
+
for i in range(cntall):
|
|
82
|
+
pgrec = PgUtil.onerecord(pgusers, i)
|
|
83
|
+
record = PgDBI.ucar_user_info(pgrec['userno'], pgrec['logname'])
|
|
84
|
+
if record:
|
|
85
|
+
modcnt += PgDBI.pgupdt(TBNAME, record, "uid = {}".format(pgrec['uid']), PgLOG.LOGWRN)
|
|
86
|
+
|
|
87
|
+
if (i%500) == 499:
|
|
88
|
+
PgLOG.pglog("{}/{} Records modifiled/processed".format(modcnt, (i+1)), PgLOG.WARNLG)
|
|
89
|
+
s = 's' if modcnt > 1 else ''
|
|
90
|
+
PgLOG.pglog("{} User Record{} modified".format(modcnt, s), PgLOG.LOGWRN)
|
|
91
|
+
return modcnt
|
|
92
|
+
|
|
93
|
+
#
|
|
94
|
+
# Fill one user for given condition userno or logname
|
|
95
|
+
#
|
|
96
|
+
def fill_one_user(userno, logname):
|
|
97
|
+
|
|
98
|
+
if userno:
|
|
99
|
+
msg = "User ID {}: ".format(userno)
|
|
100
|
+
else:
|
|
101
|
+
msg = "User Login Name {}: ".format(logname)
|
|
102
|
+
modcnt = cntadd = 0
|
|
103
|
+
newrec = PgDBI.ucar_user_info(userno, logname)
|
|
104
|
+
if not newrec:
|
|
105
|
+
PgLOG.pglog(msg + "No User info found from People DB", PgLOG.LOGWRN)
|
|
106
|
+
return
|
|
107
|
+
|
|
108
|
+
cond = 'userno = {}'.format(userno) if userno else "logname = '{}'".format(logname)
|
|
109
|
+
pgrec = PgDBI.pgget(TBNAME, "*", cond + " AND until_date is null", PgLOG.LGWNEX)
|
|
110
|
+
record = get_user_record(newrec, pgrec, (newrec['stat_flag'] == 'A'))
|
|
111
|
+
if record == None:
|
|
112
|
+
PgLOG.pglog(msg + "User record saved already", PgLOG.LOGWRN)
|
|
113
|
+
return
|
|
114
|
+
if record:
|
|
115
|
+
if pgrec:
|
|
116
|
+
if PgDBI.pgupdt(TBNAME, record, "uid = {}".format(pgrec['uid']), PgLOG.LOGWRN):
|
|
117
|
+
PgLOG.pglog(msg + "Existing User record Modified", PgLOG.LOGWRN)
|
|
118
|
+
modcnt += 1
|
|
119
|
+
else:
|
|
120
|
+
if PgDBI.pgadd(TBNAME, record, PgLOG.LGWNEX):
|
|
121
|
+
PgLOG.pglog(msg + "New user record added", PgLOG.LOGWRN)
|
|
122
|
+
cntadd += 1
|
|
123
|
+
else:
|
|
124
|
+
record = {'stat_flag' : 'C'}
|
|
125
|
+
record['until_date'] = PgUtil.adddate(newrec['start_date'], 0, 0, -1)
|
|
126
|
+
if PgDBI.pgupdt(TBNAME, record, "uid = {}".format(pgrec['uid']), PgLOG.LOGWRN):
|
|
127
|
+
PgLOG.pglog(msg + "Existing User record Closed", PgLOG.LOGWRN)
|
|
128
|
+
modcnt += 1
|
|
129
|
+
|
|
130
|
+
record = get_user_record(newrec)
|
|
131
|
+
if record and PgDBI.pgadd(TBNAME, record, PgLOG.LGWNEX):
|
|
132
|
+
PgLOG.pglog(msg + "Additional New user record added", PgLOG.LOGWRN)
|
|
133
|
+
cntadd += 1
|
|
134
|
+
|
|
135
|
+
#
|
|
136
|
+
# local function: get_user_record(orarec: refer to oracle hush record
|
|
137
|
+
# pgrecs: refer to exist, mysql hush records)
|
|
138
|
+
|
|
139
|
+
# return: a reference to a new mysql record for update or add
|
|
140
|
+
#
|
|
141
|
+
def get_user_record(orarec, pgrec = None, neworg = False):
|
|
142
|
+
|
|
143
|
+
if not orarec['email']: return None
|
|
144
|
+
|
|
145
|
+
ms = re.match("^(.+\@).+\.ucar\.edu$", orarec['email'], re.I)
|
|
146
|
+
if ms: orarec['email'] = ms.group(1) + "ucar.edu"
|
|
147
|
+
|
|
148
|
+
newrec = {}
|
|
149
|
+
if pgrec:
|
|
150
|
+
if neworg and PgUtil.diffdate(orarec['start_date'], pgrec['start_date']) <= 0:
|
|
151
|
+
neworg = False
|
|
152
|
+
if not pgrec['division'] or pgrec['division'] != orarec['division']:
|
|
153
|
+
if neworg and orarec['org_type'] == 'NCAR': return 0
|
|
154
|
+
newrec['division'] = orarec['division']
|
|
155
|
+
if orarec['org_name'] and (not pgrec['org_name'] or pgrec['org_name'] != orarec['org_name']):
|
|
156
|
+
if neworg: return 0
|
|
157
|
+
newrec['org_name'] = orarec['org_name']
|
|
158
|
+
if orarec['country'] and (not pgrec['country'] or orarec['country'] and pgrec['country'] != orarec['country']):
|
|
159
|
+
orarec['country'] = PgDBI.set_country_code(orarec)
|
|
160
|
+
if not pgrec['country'] or pgrec['country'] != orarec['country']:
|
|
161
|
+
if neworg: return 0
|
|
162
|
+
newrec['country'] = orarec['country']
|
|
163
|
+
if not pgrec['org_type'] or (orarec['org_type'] and pgrec['org_type'] != orarec['org_type']):
|
|
164
|
+
orarec['org_type'] = PgDBI.get_org_type(orarec['org_type'], orarec['email'])
|
|
165
|
+
if not pgrec['org_type'] or pgrec['org_type'] != orarec['org_type']:
|
|
166
|
+
if neworg: return 0
|
|
167
|
+
newrec['org_type'] = orarec['org_type']
|
|
168
|
+
if not pgrec['email'] or pgrec['email'] != orarec['email']:
|
|
169
|
+
if neworg: return 0
|
|
170
|
+
newrec['email'] = orarec['email']
|
|
171
|
+
if not pgrec['ucaremail'] or pgrec['ucaremail'] != orarec['ucaremail']:
|
|
172
|
+
newrec['ucaremail'] = orarec['ucaremail']
|
|
173
|
+
if 'until_date' in orarec and PgUtil.diffdate(pgrec['until_date'], orarec['until_date']):
|
|
174
|
+
newrec['until_date'] = orarec['until_date']
|
|
175
|
+
if not pgrec['userno'] or pgrec['userno'] != orarec['userno']:
|
|
176
|
+
newrec['userno'] = orarec['userno']
|
|
177
|
+
if not pgrec['upid'] or pgrec['upid'] != orarec['upid']:
|
|
178
|
+
newrec['upid'] = orarec['upid']
|
|
179
|
+
if not pgrec['logname'] or pgrec['logname'] != orarec['logname']:
|
|
180
|
+
newrec['logname'] = orarec['logname']
|
|
181
|
+
if orarec['lstname'] and (not pgrec['lstname'] or pgrec['lstname'] != orarec['lstname']):
|
|
182
|
+
newrec['lstname'] = orarec['lstname']
|
|
183
|
+
if orarec['fstname'] and (not pgrec['fstname'] or pgrec['fstname'] != orarec['fstname']):
|
|
184
|
+
newrec['fstname'] = orarec['fstname']
|
|
185
|
+
if pgrec['stat_flag'] != orarec['stat_flag']:
|
|
186
|
+
newrec['stat_flag'] = orarec['stat_flag']
|
|
187
|
+
if 'phoneno' in orarec and orarec['phoneno'] and (not pgrec['phoneno'] or pgrec['phoneno'] != orarec['phoneno']):
|
|
188
|
+
newrec['phoneno'] = orarec['phoneno']
|
|
189
|
+
if 'faxno' in orarec and orarec['faxno'] and (not pgrec['faxno'] or pgrec['faxno'] != orarec['faxno']):
|
|
190
|
+
newrec['faxno'] = orarec['faxno']
|
|
191
|
+
if orarec['start_date'] and (not pgrec['start_date'] or PgUtil.diffdate(pgrec['start_date'], orarec['start_date']) > 0):
|
|
192
|
+
newrec['start_date'] = orarec['start_date']
|
|
193
|
+
elif orarec['stat_flag'] == 'A':
|
|
194
|
+
newrec['upid'] = orarec['upid']
|
|
195
|
+
newrec['userno'] = orarec['userno']
|
|
196
|
+
newrec['logname'] = orarec['logname']
|
|
197
|
+
newrec['lstname'] = orarec['lstname']
|
|
198
|
+
newrec['fstname'] = orarec['fstname']
|
|
199
|
+
newrec['stat_flag'] = orarec['stat_flag']
|
|
200
|
+
if orarec['start_date']: newrec['start_date'] = orarec['start_date']
|
|
201
|
+
if 'until_date' in orarec: newrec['until_date'] = orarec['until_date']
|
|
202
|
+
newrec['division'] = orarec['division']
|
|
203
|
+
newrec['org_name'] = orarec['org_name']
|
|
204
|
+
newrec['org_type'] = PgDBI.get_org_type(orarec['org_type'], orarec['email'])
|
|
205
|
+
newrec['country'] = PgDBI.set_country_code(orarec['email'], orarec['country'])
|
|
206
|
+
newrec['email'] = orarec['email']
|
|
207
|
+
newrec['ucaremail'] = orarec['ucaremail']
|
|
208
|
+
if 'phoneno' in orarec: newrec['phoneno'] = orarec['phoneno']
|
|
209
|
+
if 'faxno' in orarec: newrec['faxno'] = orarec['faxno']
|
|
210
|
+
|
|
211
|
+
return newrec if newrec else None
|
|
212
|
+
|
|
213
|
+
#
|
|
214
|
+
# call main() to start program
|
|
215
|
+
#
|
|
216
|
+
if __name__ == "__main__": main()
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
|
|
2
|
+
Retrieves user information from ORACLE SERVER and fill
|
|
3
|
+
table 'user' in MySQL database 'dssdb'.
|
|
4
|
+
|
|
5
|
+
Usage: filluser [-b] [-i] [-n UserNumber] [-u UserLonginName]
|
|
6
|
+
|
|
7
|
+
select one of the options, -i, -n or -u each time to run this application.
|
|
8
|
+
|
|
9
|
+
- Option -b, log process information into logfile only;
|
|
10
|
+
|
|
11
|
+
- Option -i, get users with incomplete information in 'dssdb.user';
|
|
12
|
+
|
|
13
|
+
- Option -n, get users by their user numbers on NCAR system;
|
|
14
|
+
|
|
15
|
+
- Option -u, get users by their login names on NCAR system;
|
|
16
|
+
|
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
#
|
|
3
|
+
##################################################################################
|
|
4
|
+
#
|
|
5
|
+
# Title : logarch
|
|
6
|
+
# Author : Zaihua Ji, zji@ucar.edu
|
|
7
|
+
# Date : 11/19/2020
|
|
8
|
+
# 2025-03-26 transferred to package rda_python_metrics from
|
|
9
|
+
# https://github.com/NCAR/rda-utility-programs.git
|
|
10
|
+
# Purpose : archive log files automatically
|
|
11
|
+
#
|
|
12
|
+
# Github : https://github.com/NCAR/rda-python-metrics.git
|
|
13
|
+
#
|
|
14
|
+
##################################################################################
|
|
15
|
+
|
|
16
|
+
import sys
|
|
17
|
+
import re
|
|
18
|
+
from os import path as op
|
|
19
|
+
import glob
|
|
20
|
+
from rda_python_common import PgLOG
|
|
21
|
+
from rda_python_common import PgUtil
|
|
22
|
+
from rda_python_common import PgFile
|
|
23
|
+
from rda_python_common import PgSIG
|
|
24
|
+
|
|
25
|
+
# the defined options for archiving different logs
|
|
26
|
+
WLOG = 0x01 # archive web log
|
|
27
|
+
TLOG = 0x02 # archive tds log
|
|
28
|
+
DLOG = 0x04 # archive dssdb logs
|
|
29
|
+
SLOG = 0x08 # append dssdb sub batch logs
|
|
30
|
+
ALOG = 0x10 # archive AWS web log
|
|
31
|
+
|
|
32
|
+
LOGS = {
|
|
33
|
+
'OPTION' : 0,
|
|
34
|
+
'AWSLOG' : PgLOG.PGLOG["TRANSFER"] + "/AWSera5log",
|
|
35
|
+
'WEBLOG' : PgLOG.PGLOG["DSSDATA"] + "/work/logs/gridftp",
|
|
36
|
+
'MGTLOG' : "/data/logs",
|
|
37
|
+
'TDSLOG' : "/data/logs/nginx",
|
|
38
|
+
'RDALOG' : PgLOG.PGLOG['LOGPATH'],
|
|
39
|
+
'LOGPATH' : None,
|
|
40
|
+
'CHKLOG' : 1,
|
|
41
|
+
'DECSLOGS' : PgLOG.PGLOG['DECSHOME'] + "/DECSLOGS"
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
BIDS = {}
|
|
45
|
+
|
|
46
|
+
#
|
|
47
|
+
# main function to excecute this script
|
|
48
|
+
#
|
|
49
|
+
def main():
|
|
50
|
+
|
|
51
|
+
pgname = "logarch"
|
|
52
|
+
argv = sys.argv[1:]
|
|
53
|
+
smonth = None
|
|
54
|
+
|
|
55
|
+
# set different log file
|
|
56
|
+
PgLOG.PGLOG['LOGFILE'] = pgname + '.log'
|
|
57
|
+
PgLOG.set_suid(PgLOG.PGLOG['EUID'])
|
|
58
|
+
|
|
59
|
+
option = None
|
|
60
|
+
for arg in argv:
|
|
61
|
+
ms = re.match(r'^-([abdmnpstw])', arg)
|
|
62
|
+
if ms:
|
|
63
|
+
option = ms.group(1)
|
|
64
|
+
if option in 'mp': continue
|
|
65
|
+
if option == "b":
|
|
66
|
+
PgLOG.PGLOG['BCKGRND'] = 1
|
|
67
|
+
elif option == "d":
|
|
68
|
+
LOGS['OPTION'] |= DLOG
|
|
69
|
+
elif option == "w":
|
|
70
|
+
LOGS['OPTION'] |= WLOG
|
|
71
|
+
elif option == "a":
|
|
72
|
+
LOGS['OPTION'] |= ALOG
|
|
73
|
+
elif option == "s":
|
|
74
|
+
LOGS['OPTION'] |= SLOG
|
|
75
|
+
elif option == "t":
|
|
76
|
+
LOGS['OPTION'] |= TLOG
|
|
77
|
+
elif option == "n":
|
|
78
|
+
LOGS['CHKLOG'] = 0
|
|
79
|
+
option = None
|
|
80
|
+
elif option == 'm':
|
|
81
|
+
smonth = arg
|
|
82
|
+
elif option == 'p':
|
|
83
|
+
LOGS['LOGPATH'] = arg
|
|
84
|
+
else:
|
|
85
|
+
PgLOG.pglog(arg + ": Invalid Option", PgLOG.LGWNEX)
|
|
86
|
+
option = None
|
|
87
|
+
|
|
88
|
+
if not LOGS['OPTION']: PgLOG.show_usage(pgname)
|
|
89
|
+
PgLOG.cmdlog("{} {}".format(pgname, ' '.join(argv)))
|
|
90
|
+
|
|
91
|
+
if LOGS['OPTION']&SLOG: append_dssdb_sublog()
|
|
92
|
+
if LOGS['OPTION']&DLOG: archive_dssdb_log()
|
|
93
|
+
if LOGS['OPTION']&WLOG: archive_web_log(smonth)
|
|
94
|
+
if LOGS['OPTION']&ALOG: archive_aws_log(smonth)
|
|
95
|
+
if LOGS['OPTION']&TLOG: archive_tds_log(smonth)
|
|
96
|
+
|
|
97
|
+
PgLOG.cmdlog(None, 0, PgLOG.LOGWRN|PgLOG.SNDEML)
|
|
98
|
+
PgLOG.pgexit(0)
|
|
99
|
+
|
|
100
|
+
def get_year_month(smonth):
|
|
101
|
+
|
|
102
|
+
if not smonth: smonth = PgUtil.adddate(PgUtil.curdate('YYYY-MM') + '-01', 0, -1, 0, 'YYYY-MM')
|
|
103
|
+
ms = re.match(r'^(\d+)-(\d+)', smonth)
|
|
104
|
+
return [ms.group(1), '{:02}'.format(int(ms.group(2)))]
|
|
105
|
+
|
|
106
|
+
#
|
|
107
|
+
# Archive globus web log files to LOGS['DECSLOGS']
|
|
108
|
+
#
|
|
109
|
+
def archive_web_log(smonth):
|
|
110
|
+
|
|
111
|
+
(yr, mn) = get_year_month(smonth)
|
|
112
|
+
PgFile.change_local_directory(LOGS['DECSLOGS'], PgLOG.LGEREM)
|
|
113
|
+
logpath = LOGS['LOGPATH'] if LOGS['LOGPATH'] else LOGS['WEBLOG']
|
|
114
|
+
afile = "globusweb{}-{}.log.tar".format(yr, mn)
|
|
115
|
+
dfile = "./WEBLOG/{}.gz".format(afile)
|
|
116
|
+
if op.exists(dfile):
|
|
117
|
+
PgLOG.pglog("{}: file exists already under {}, remove it before backup again".format(dfile, LOGS['DECSLOGS']), PgLOG.LGWNEM)
|
|
118
|
+
return
|
|
119
|
+
|
|
120
|
+
if op.exists(afile): PgFile.delete_local_file(afile)
|
|
121
|
+
|
|
122
|
+
logfiles = sorted(glob.glob("{}/access_log_gridftp??_{}??{}".format(logpath, mn, yr)))
|
|
123
|
+
topt = '-cvf'
|
|
124
|
+
tcnt = 0
|
|
125
|
+
for logfile in logfiles:
|
|
126
|
+
if not op.exists(logfile):
|
|
127
|
+
PgLOG.pglog(logfile + ": file not exists", PgLOG.LGWNEM)
|
|
128
|
+
continue
|
|
129
|
+
if op.getsize(logfile) == 0:
|
|
130
|
+
PgLOG.pglog(logfile + ": empty file", PgLOG.LGWNEM)
|
|
131
|
+
continue
|
|
132
|
+
lfile = op.basename(logfile)
|
|
133
|
+
tcmd = "tar {} {} -C {} {}".format(topt, afile, logpath, lfile)
|
|
134
|
+
tcnt += PgLOG.pgsystem(tcmd, PgLOG.LGWNEM, 5)
|
|
135
|
+
topt = '-uvf'
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
if tcnt > 0:
|
|
139
|
+
PgLOG.pgsystem("gzip " + afile, PgLOG.LGWNEM, 5)
|
|
140
|
+
afile += '.gz'
|
|
141
|
+
PgFile.move_local_file(dfile, afile, PgLOG.LGWNEM)
|
|
142
|
+
s = 's' if tcnt > 1 else ''
|
|
143
|
+
PgLOG.pglog("{}: {} globus log{} tarred, gzipped and archived at {}".format(afile, tcnt, s, PgLOG.current_datetime()), PgLOG.LGWNEM)
|
|
144
|
+
|
|
145
|
+
#
|
|
146
|
+
# Archive AWS web log files to LOGS['DECSLOGS']
|
|
147
|
+
#
|
|
148
|
+
def archive_aws_log(smonth):
|
|
149
|
+
|
|
150
|
+
(yr, mn) = get_year_month(smonth)
|
|
151
|
+
PgFile.change_local_directory(LOGS['DECSLOGS'], PgLOG.LGEREM)
|
|
152
|
+
logpath = LOGS['LOGPATH'] if LOGS['LOGPATH'] else LOGS['AWSLOG']
|
|
153
|
+
afile = "awsweb{}-{}.log.tar".format(yr, mn)
|
|
154
|
+
dfile = "./AWSLOG/{}.gz".format(afile)
|
|
155
|
+
if op.exists(dfile):
|
|
156
|
+
PgLOG.pglog("{}: file exists already under {}, remove it before backup again".format(dfile, LOGS['DECSLOGS']), PgLOG.LGWNEM)
|
|
157
|
+
return
|
|
158
|
+
|
|
159
|
+
if op.exists(afile): PgFile.delete_local_file(afile)
|
|
160
|
+
|
|
161
|
+
lfile = "{}/{}".format(yr, mn)
|
|
162
|
+
tcmd = "tar -cvf {} -C {} {}".format(afile, logpath, lfile)
|
|
163
|
+
PgLOG.pgsystem(tcmd, PgLOG.LGWNEM, 5)
|
|
164
|
+
|
|
165
|
+
PgLOG.pgsystem("gzip " + afile, PgLOG.LGWNEM, 5)
|
|
166
|
+
afile += '.gz'
|
|
167
|
+
PgFile.move_local_file(dfile, afile, PgLOG.LGWNEM)
|
|
168
|
+
PgLOG.pglog("{}: AWS logs tarred, gzipped and archived at {}".format(afile, PgLOG.current_datetime()), PgLOG.LGWNEM)
|
|
169
|
+
|
|
170
|
+
#
|
|
171
|
+
# Archive monthly tds logs under DECSLOGS/TDSLOG/
|
|
172
|
+
#
|
|
173
|
+
def archive_tds_log(smonth):
|
|
174
|
+
|
|
175
|
+
(yr, mn) = get_year_month(smonth)
|
|
176
|
+
PgFile.change_local_directory(LOGS['DECSLOGS'], PgLOG.LGEREM)
|
|
177
|
+
logpath = LOGS['LOGPATH'] if LOGS['LOGPATH'] else LOGS['TDSLOG']
|
|
178
|
+
afile = "thredds{}-{}.log.tar".format(yr, mn)
|
|
179
|
+
dfile = "./TDSLOG/{}.gz".format(afile)
|
|
180
|
+
if op.exists(dfile):
|
|
181
|
+
PgLOG.pglog("{}: file exists already under {}, remove it before backup again".format(dfile, LOGS['DECSLOGS']), PgLOG.LGWNEM)
|
|
182
|
+
return
|
|
183
|
+
|
|
184
|
+
if op.exists(afile): PgFile.delete_local_file(afile)
|
|
185
|
+
|
|
186
|
+
logfiles = sorted(glob.glob("{}/{}-{}-??.access.log".format(logpath, yr, mn)))
|
|
187
|
+
topt = '-cvf'
|
|
188
|
+
tcnt = 0
|
|
189
|
+
for logfile in logfiles:
|
|
190
|
+
if not op.exists(logfile):
|
|
191
|
+
PgLOG.pglog(logfile + ": file not exists", PgLOG.LGWNEM)
|
|
192
|
+
continue
|
|
193
|
+
if op.getsize(logfile) == 0:
|
|
194
|
+
PgLOG.pglog(logfile + ": empty file", PgLOG.LGWNEM)
|
|
195
|
+
continue
|
|
196
|
+
lfile = op.basename(logfile)
|
|
197
|
+
tcmd = "tar {} {} -C {} {}".format(topt, afile, logpath, lfile)
|
|
198
|
+
tcnt += PgLOG.pgsystem(tcmd, PgLOG.LGWNEM, 5)
|
|
199
|
+
topt = '-uvf'
|
|
200
|
+
|
|
201
|
+
if tcnt > 0:
|
|
202
|
+
PgLOG.pgsystem("gzip " + afile, PgLOG.LGWNEM, 5)
|
|
203
|
+
afile += '.gz'
|
|
204
|
+
PgFile.move_local_file(dfile, afile, PgLOG.LGWNEM)
|
|
205
|
+
s = 's' if tcnt > 1 else ''
|
|
206
|
+
PgLOG.pglog("{}: {} thredds log{} tarred, gzipped and archived at {}".format(afile, tcnt, s, PgLOG.current_datetime()), PgLOG.LGWNEM)
|
|
207
|
+
|
|
208
|
+
#
|
|
209
|
+
# Archive current dssdb logs onto hpss under /DSS/RDADB/LOG
|
|
210
|
+
#
|
|
211
|
+
def archive_dssdb_log():
|
|
212
|
+
|
|
213
|
+
cntall = 0
|
|
214
|
+
logfile = "{}_dblog{}.tar".format(PgLOG.PGLOG['HOSTNAME'], PgUtil.curdate("YYMMDD"))
|
|
215
|
+
dfile = "{}/RDADB/LOG/{}.gz".format(LOGS['DECSLOGS'], logfile)
|
|
216
|
+
if LOGS['CHKLOG'] and check_decs_archive(dfile):
|
|
217
|
+
return PgLOG.pglog(dfile + ": archived already", PgLOG.LGWNEM)
|
|
218
|
+
|
|
219
|
+
PgFile.change_local_directory(LOGS['RDALOG'], PgLOG.LWEMEX)
|
|
220
|
+
|
|
221
|
+
# collect all the large log/err files
|
|
222
|
+
files = sorted(glob.glob("*.log") + glob.glob("*.err"))
|
|
223
|
+
for file in files:
|
|
224
|
+
info = PgFile.check_local_file(file, 2)
|
|
225
|
+
if(not info or info['data_size'] < 10000): continue # skip log files small than 10KB
|
|
226
|
+
|
|
227
|
+
PgLOG.pgsystem("cp -p -f {} backup/{}".format(file, file), PgLOG.LWEMEX, 5)
|
|
228
|
+
if info['logname'] != PgLOG.PGLOG['RDAUSER']: PgLOG.pgsystem("rm -rf " + file)
|
|
229
|
+
PgLOG.pgsystem("cat /dev/null > " + file, 0, 1024)
|
|
230
|
+
if op.exists(logfile):
|
|
231
|
+
PgLOG.pgsystem("tar -uvf {} -C backup {}".format(logfile, file), PgLOG.LWEMEX, 5)
|
|
232
|
+
else:
|
|
233
|
+
PgLOG.pgsystem("tar -cvf {} -C backup {}".format(logfile, file), PgLOG.LWEMEX, 5)
|
|
234
|
+
cntall += 1
|
|
235
|
+
|
|
236
|
+
if cntall > 0:
|
|
237
|
+
if LOGS['CHKLOG']:
|
|
238
|
+
if backup_decsdata_file(logfile, logfile, dfile, 1):
|
|
239
|
+
s = 's' if cntall > 1 else ''
|
|
240
|
+
PgLOG.pglog("{} dssdb log{} archived at {}".format(cntall, s, PgLOG.current_datetime()), PgLOG.LGWNEM)
|
|
241
|
+
else:
|
|
242
|
+
PgLOG.pgsystem("gzip " + logfile, PgLOG.LWEMEX, 5)
|
|
243
|
+
logfile += ".gz"
|
|
244
|
+
PgLOG.pgsystem("mv -f {} backup/".format(logfile), PgLOG.LWEMEX, 5)
|
|
245
|
+
|
|
246
|
+
#
|
|
247
|
+
# append individual batch logs to common stdout/error logs
|
|
248
|
+
#
|
|
249
|
+
def append_dssdb_sublog():
|
|
250
|
+
|
|
251
|
+
logpath = LOGS['LOGPATH'] if LOGS['LOGPATH'] else LOGS['RDALOG']
|
|
252
|
+
PgFile.change_local_directory(logpath, PgLOG.LGWNEX);
|
|
253
|
+
|
|
254
|
+
if not PgLOG.valid_command(PgLOG.BCHCMDS['PBS']):
|
|
255
|
+
PgLOG.pglog("Must run on PBS Nodes to append sublogs", PgLOG.LGEREM)
|
|
256
|
+
return
|
|
257
|
+
|
|
258
|
+
add_sublog_files('OU', 'log')
|
|
259
|
+
add_sublog_files('ER', 'err', 37)
|
|
260
|
+
|
|
261
|
+
#
|
|
262
|
+
# add individual sublog files to the common ones
|
|
263
|
+
#
|
|
264
|
+
def add_sublog_files(fext, sext, minsize = 0):
|
|
265
|
+
|
|
266
|
+
subname = 'rdaqsub'
|
|
267
|
+
pattern = r'^(\d+)\.'
|
|
268
|
+
afiles = PgFile.local_glob("{}/*.{}".format(subname, fext), 3, PgLOG.LGWNEX)
|
|
269
|
+
if not afiles:
|
|
270
|
+
PgLOG.pglog("{}: NO '{}' file found to collect".format(subname, fext), PgLOG.LOGWRN)
|
|
271
|
+
return
|
|
272
|
+
if minsize:
|
|
273
|
+
tmin = PgLOG.PGLOG['MINSIZE']
|
|
274
|
+
PgLOG.PGLOG['MINSIZE'] = minsize
|
|
275
|
+
acnt = fcnt = 0
|
|
276
|
+
sfiles = {}
|
|
277
|
+
for afile in afiles:
|
|
278
|
+
fcnt += 1
|
|
279
|
+
finfo = afiles[afile]
|
|
280
|
+
sfiles[op.basename(afile)] = "{} {} {}".format(finfo['date_modified'], finfo['time_modified'], finfo['logname'])
|
|
281
|
+
|
|
282
|
+
afiles = sorted(sfiles)
|
|
283
|
+
logfile = "PBS_sublog.{}".format(sext)
|
|
284
|
+
for afile in afiles:
|
|
285
|
+
ms = re.match(pattern, afile)
|
|
286
|
+
if ms:
|
|
287
|
+
bid = int(ms.group(1))
|
|
288
|
+
if bid not in BIDS: BIDS[bid] = PgSIG.check_pbs_process(bid, afile)
|
|
289
|
+
if BIDS[bid] > 0: continue
|
|
290
|
+
else:
|
|
291
|
+
continue
|
|
292
|
+
|
|
293
|
+
sfile = "{}/{}".format(subname, afile)
|
|
294
|
+
if minsize and PgFile.local_file_size(sfile, 1) < 1: continue
|
|
295
|
+
PgLOG.pgsystem("echo '{}: {}' >> {}".format(bid, sfiles[afile], logfile), PgLOG.LGWNEX, 5+1024)
|
|
296
|
+
PgLOG.pgsystem("cat {} >> {}".format(sfile, logfile), PgLOG.LGWNEX, 5+1024)
|
|
297
|
+
PgFile.delete_local_file(sfile, PgLOG.LOGWRN)
|
|
298
|
+
acnt += 1
|
|
299
|
+
if fcnt > 0:
|
|
300
|
+
s = 's' if fcnt > 1 else ''
|
|
301
|
+
PgLOG.pglog("{}: {} of {} '{}' file{} appended at {}".format(logfile, acnt, fcnt, fext, s, PgLOG.current_datetime()), PgLOG.LOGWRN)
|
|
302
|
+
|
|
303
|
+
if minsize: PgLOG.PGLOG['MINSIZE'] = tmin
|
|
304
|
+
|
|
305
|
+
#
|
|
306
|
+
# backup a log file to decsdata area
|
|
307
|
+
#
|
|
308
|
+
def backup_decsdata_file(logfile, locfile, dfile, skipcheck = 0):
|
|
309
|
+
|
|
310
|
+
ret = 0
|
|
311
|
+
if op.getsize(logfile) == 0:
|
|
312
|
+
PgLOG.pglog(logfile + ": Empty log file", PgLOG.LGWNEM)
|
|
313
|
+
return 0
|
|
314
|
+
if not skipcheck and check_decs_archive(dfile, logfile, 1):
|
|
315
|
+
return 0 # archived already
|
|
316
|
+
|
|
317
|
+
if locfile != logfile:
|
|
318
|
+
locfile = "{}/{}".format(PgLOG.PGLOG['TMPPATH'], locfile)
|
|
319
|
+
if not PgFile.local_copy_local(locfile, logfile, PgLOG.LGWNEM): return 0
|
|
320
|
+
lfile = locfile
|
|
321
|
+
locfile += ".gz"
|
|
322
|
+
if PgFile.check_local_file(locfile, 0, PgLOG.LGWNEM): PgFile.delete_local_file(locfile, PgLOG.LGWNEM)
|
|
323
|
+
PgLOG.pgsystem("gzip " + lfile, PgLOG.LWEMEX, 5)
|
|
324
|
+
|
|
325
|
+
PgLOG.pglog("archive {} to {}".format(locfile, dfile), PgLOG.LGWNEM)
|
|
326
|
+
if PgFile.local_copy_local(dfile, locfile, PgLOG.LGWNEM):
|
|
327
|
+
size = check_decs_archive(dfile)
|
|
328
|
+
if size:
|
|
329
|
+
PgLOG.pglog("{}: archived as {}({})".format(logfile, dfile, size), PgLOG.LGWNEM)
|
|
330
|
+
ret = 1
|
|
331
|
+
|
|
332
|
+
if op.exists(locfile) and ret: PgLOG.pgsystem("rm -f " + locfile, PgLOG.LGWNEM)
|
|
333
|
+
|
|
334
|
+
return ret
|
|
335
|
+
|
|
336
|
+
#
|
|
337
|
+
# return decs file size if archived already; otherwise 0
|
|
338
|
+
#
|
|
339
|
+
def check_decs_archive(afile, logfile = None, checktime = 0):
|
|
340
|
+
|
|
341
|
+
ainfo = PgFile.check_local_file(afile, 1)
|
|
342
|
+
if not ainfo: return 0
|
|
343
|
+
size = ainfo['data_size']
|
|
344
|
+
if logfile:
|
|
345
|
+
linfo = PgFile.check_local_file(logfile, 1, PgLOG.LGWNEM)
|
|
346
|
+
if linfo:
|
|
347
|
+
if checktime:
|
|
348
|
+
if linfo['date_modified'] > ainfo['date_modified']: size = 0
|
|
349
|
+
elif size < linfo['data_size']:
|
|
350
|
+
size = 0
|
|
351
|
+
|
|
352
|
+
if size > 0: PgLOG.pglog("{}: archived on {} as {}({})".format(logfile, ainfo['date_modified'], afile, size), PgLOG.LGWNEM)
|
|
353
|
+
|
|
354
|
+
return size
|
|
355
|
+
|
|
356
|
+
#
|
|
357
|
+
# call main() to start program
|
|
358
|
+
#
|
|
359
|
+
if __name__ == "__main__": main()
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
|
|
2
|
+
Archive RDA log files onto to DECSDATA area. This application can be run
|
|
3
|
+
at any time. It checks if the given log files are archived or not and will
|
|
4
|
+
ignore the ones that are backed up already.
|
|
5
|
+
|
|
6
|
+
Usage: logarch [-b] [-a] [-d] [-w] [-s] [-t] [-p LogPath] \
|
|
7
|
+
[-m YearMonth] [-n]
|
|
8
|
+
|
|
9
|
+
- Option -b, do not display processing info on screen;
|
|
10
|
+
|
|
11
|
+
- Option -a, archive aws log files;
|
|
12
|
+
|
|
13
|
+
- Option -d, archive dssdb log files;
|
|
14
|
+
|
|
15
|
+
- Option -p, provide a LogPath if not the fefault one;
|
|
16
|
+
|
|
17
|
+
- Option -s, append PBS sublog files to common log files;
|
|
18
|
+
|
|
19
|
+
- Option -t, archive tds log files;
|
|
20
|
+
|
|
21
|
+
- Option -w, archive web log files;
|
|
22
|
+
|
|
23
|
+
- Option -m, Provided a specified YearMonth (in form of YYYY-MM) to backup logs;
|
|
24
|
+
|
|
25
|
+
- Option -n, do not check if a log file is backed up already;
|
|
26
|
+
|
|
27
|
+
Set at least one of the options -a, -d, -s, -t and -w to run this application.
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
#*******************************************************************
|
|
3
|
+
# Title : pgperson.py
|
|
4
|
+
# Author : Zaihua Ji, zji@ucar.edu
|
|
5
|
+
# Date : 2025-03-27
|
|
6
|
+
# Purpose : utility program to retrieve user info from People DB
|
|
7
|
+
#
|
|
8
|
+
# Github : https://github.com/NCAR/rda-python-metrics.git
|
|
9
|
+
#
|
|
10
|
+
#*******************************************************************
|
|
11
|
+
|
|
12
|
+
import httplib2
|
|
13
|
+
import json
|
|
14
|
+
import sys
|
|
15
|
+
from rda_python_common import PgLOG
|
|
16
|
+
|
|
17
|
+
PERSON = [
|
|
18
|
+
"upid", # Unique person id
|
|
19
|
+
"username", # UCAR login user name
|
|
20
|
+
"email", # Email address
|
|
21
|
+
"uid", # Scientist id or Unix id
|
|
22
|
+
"firstName", # First name
|
|
23
|
+
"lastName", # Last name
|
|
24
|
+
"forwardEmail" # Forward Email address
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
urlfmt="https://people.api.ucar.edu/persons?{}={}&searchScope=all&includeActive=true&includeInactive=true&searchType=advancedSearch"
|
|
28
|
+
|
|
29
|
+
#
|
|
30
|
+
# main function to excecute this script
|
|
31
|
+
#
|
|
32
|
+
def main():
|
|
33
|
+
|
|
34
|
+
pgname = "pgperson"
|
|
35
|
+
argv = sys.argv[1:]
|
|
36
|
+
optstr = '|'.join(PERSON)
|
|
37
|
+
if sys.argc != 3:
|
|
38
|
+
print("Usage: {} -({}) OptopnValue".format(pgname, optstr))
|
|
39
|
+
sys.exit(0)
|
|
40
|
+
|
|
41
|
+
option = optval = None
|
|
42
|
+
for arg in argv:
|
|
43
|
+
if option:
|
|
44
|
+
optval = arg
|
|
45
|
+
elif arg[0] == '-':
|
|
46
|
+
option = arg[1:]
|
|
47
|
+
if option not in PERSON:
|
|
48
|
+
PgLOG.pglog("{}: unknown option, must be -({})".format(arg, optstr), PgLOG.LGEREX)
|
|
49
|
+
else:
|
|
50
|
+
PgLOG.pglog("{}: Value passed in without leading option -({})".format(arg, optstr), PgLOG.LGEREX)
|
|
51
|
+
|
|
52
|
+
headers = {'Content-type': 'application/json'}
|
|
53
|
+
http=httplib2.Http()
|
|
54
|
+
url = urlfmt.format(option, optval)
|
|
55
|
+
response, content = http.request(url, 'GET', headers=headers)
|
|
56
|
+
status = response.status
|
|
57
|
+
if status == 200:
|
|
58
|
+
persons=json.loads(content)
|
|
59
|
+
for person in persons:
|
|
60
|
+
for key, value in person.items():
|
|
61
|
+
print("{}<=>{}".format(key, value))
|
|
62
|
+
elif status == 399:
|
|
63
|
+
print(content)
|
|
64
|
+
elif status == 500:
|
|
65
|
+
print('Server error')
|
|
66
|
+
|
|
67
|
+
sys.exit(0)
|
|
68
|
+
|
|
69
|
+
#
|
|
70
|
+
# call main() to start program
|
|
71
|
+
#
|
|
72
|
+
if __name__ == "__main__": main()
|