-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathmonitor.py
More file actions
executable file
·239 lines (220 loc) · 11.9 KB
/
monitor.py
File metadata and controls
executable file
·239 lines (220 loc) · 11.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
#!/usr/bin/python3.5 -W ignore
from container import Server
from cpbo import Config
from cpbo import ServerBO
from cpbo import ContainerBO
from pylxd import Client
from time import sleep
from time import time
from json import load, dump
from constants import Constants
class Monitor():
overlogFile="./log/over/log_"+str(int(time()*1000));
alllogFile="./log/alllog_"+str(int(time()*1000));
def __init__(self):
Config.init()
print("Initialitation done.");
self.cp = Server()
self.monitorIteration=0;
self.sla=Server.SLA;
print("Monitor Started...");
def run(self):
while(True):
print("-----------------------------------------------------------------------\n");
self.monitorIteration+=1;
self.periodicMonitor();
sleep(Constants.MonitorDuration);
def periodicMonitor(self):
cp=self.cp;
containers=cp.getAllContainersStatus();
cOverCList=self.getOverLoadServer(containers);
cUnderList=self.getUnderLoadServer(containers);
n=len(cp.servers);
# Trying for container resize
cToMigrate=list();
#soc: server's overload container list
for i in range(n):
sContToMigare=self.tryServerContainerResizing(cOverCList[i],cUnderList[i]);
cToMigrate.append(sContToMigare);
def tryServerContainerResizing(self,scOverCList,scUnderList):
#containers to migrate because it can't be resized
ocRemaining=self.trySCROneOnOne(scOverCList,scUnderList);
ocRemaining=self.trySCROneToMany(ocRemaining,scUnderList);
return ocRemaining;
'''
-----------------------------------------------------------
Desc: Try Server Container Resize One-On-One
---------------------------------------------------------
'''
def trySCROneOnOne(self,scOverList,scUnderList):
ocRemaining=list();
print("#OneOnOne: Per server overloaded list",len(scOverList));
for ocbo in scOverList:
#print("[OneOnOne: Overload Cname %s by amount %s ]"%(ocbo.name,ocbo.expectedMemSize));
ucbo=self.findSingleContainerToResize(ocbo.expectedMemSize,scUnderList);
if(ucbo==None):
print("[OneOnOne: No appropiate container found for (%s,%s) which needs memory %sMB]"%(ocbo.sname,ocbo.name,ocbo.expectedMemSize//Constants.MBtoKB))
#no container to resize. Going for migration.
ocRemaining.append(ocbo);
else:
#resize;
print("OneOnOne: Resizing (%s,%s) which needs memory %sMB using container (%s,%s)"%(ocbo.sname,ocbo.name,ocbo.expectedMemSize//Constants.MBtoKB,ucbo.sname,ucbo.name))
uMaxMem=ucbo.getMemoryLimit();
oMaxMem=ocbo.getMemoryLimit();
uNewMem=uMaxMem-ocbo.expectedMemSize;
oNewMem=oMaxMem+ocbo.expectedMemSize;
ucbo.setMemoryLimit(uNewMem);
ocbo.setMemoryLimit(oNewMem);
ucbo.expectedMemSize=ucbo.expectedMemSize-ocbo.expectedMemSize;
ocbo.expectedMemSize=0;
print("OneOnOne: Underload Containers (%s,%s) Mem Change %dMB -- > %dMB"%(ocbo.sname,ocbo.name,uMaxMem//Constants.MBtoKB,uNewMem//Constants.MBtoKB))
print("OneOnOne: Overload Containers (%s,%s) Mem Change %dMB -- > %dMB"%(ocbo.sname,ocbo.name,oMaxMem//Constants.MBtoKB,oNewMem//Constants.MBtoKB))
return ocRemaining;
def findSingleContainerToResize(self,expectedMemSize,cUnderList):
for ucbo in cUnderList:
if(expectedMemSize<ucbo.expectedMemSize):
return ucbo;
return None;
'''
-----------------------------------------------------------
Desc: Try Server Container Resize One-On-Many
---------------------------------------------------------
'''
def trySCROneToMany(self,scOverList,scUnderList):
ocRemaining=list();
print("#ManyOnOne: Per server overloaded list",len(scOverList));
isResized=False;
for ocbo in scOverList:
#print("[OneOnMany: Overload Cname:%s]"%(ocbo.name));
isResized=False;
for ucbo in scUnderList:
if(ucbo.expectedMemSize>1 and ocbo.expectedMemSize>1):
#resize;
isResized=True;
print(">ManyOnOne: Resizing (%s,%s) which needs memory %sMB using container (%s,%s)"%(ocbo.sname,ocbo.name,ocbo.expectedMemSize//Constants.MBtoKB,ucbo.sname,ucbo.name))
incMem= ( ucbo.expectedMemSize if ocbo.expectedMemSize >= ucbo.expectedMemSize else ocbo.expectedMemSize);
uMaxMem=ucbo.getMemoryLimit();
oMaxMem=ocbo.getMemoryLimit();
uNewMem=uMaxMem-incMem;
oNewMem=oMaxMem+incMem;
remainingMem=ocbo.expectedMemSize-incMem;
#print("incMem",incMem//Constants.MBtoKB);
#print("uMaxMem",uMaxMem//Constants.MBtoKB);
#print("ucbo.expectedMemSize",ucbo.expectedMemSize//Constants.MBtoKB);
#print("umem",uNewMem//Constants.MBtoKB);
#print("oMaxMem",oMaxMem//Constants.MBtoKB);
#print("ocbo.expectedMemSize",ocbo.expectedMemSize//Constants.MBtoKB);
#print("oNewMem",oNewMem//Constants.MBtoKB);
#print("delta:",remainingMem//Constants.MBtoKB);
ucbo.setMemoryLimit(uNewMem);
ocbo.setMemoryLimit(oNewMem);
ucbo.expectedMemSize=0;
ocbo.expectedMemSize=remainingMem;
print("ManyOnOne: Underload Containers (%s,%s) Mem Change %dMB -- > %dMB"%(ocbo.sname,ocbo.name,uMaxMem//Constants.MBtoKB,uNewMem//Constants.MBtoKB))
print("ManyOnOne: Overload Containers (%s,%s) Mem Change %dMB -- > %dMB"%(ocbo.sname,ocbo.name,oMaxMem//Constants.MBtoKB,oNewMem//Constants.MBtoKB))
if(not isResized):
#no container to resize. Going for nextphase.
print("~[ManyOnOne: No appropiate containers found for (%s,%s) which needs memory %sMB]"%(ocbo.sname,ocbo.name,ocbo.expectedMemSize//Constants.MBtoKB))
ocRemaining.append(ocbo);
elif(ocbo.expectedMemSize>0):
print("~[ManyOnOne: Unable to Resize (%s,%s) which needs memory %sMB completely.]"%(ocbo.sname,ocbo.name,ocbo.expectedMemSize//Constants.MBtoKB));
return ocRemaining;
'''
------------------------------------------------
Desc: Under loaded server
-------------------------------------------------
'''
def getUnderLoadServer(self,containers):
cp=self.cp;
underList=list();
sla=self.sla;
#sc: server's containers
for sc in containers:
scList=list();
for cbo in sc:
#line to be removed
if (cbo.sname not in sla):
print("~Warning: Server %s is not in SLA."%(cbo.sname ))
continue;
elif(cbo.name not in sla[cbo.sname]):
print("~Warning: Container %s of Server %s is not in SLA."%(cbo.name,cbo.sname ));
continue;
if not(cbo.isRunning()):
print("~Warning: Container %s of Server %s is not RUNNING."%(cbo.name,cbo.sname ))
continue
#checking container is underflow or not
curMem=cbo.getMemoryLimit();
u=cbo.mem_util;
uPercent=u/curMem;
if(uPercent < Constants.MemThresholdPercent):
delta=Constants.MemThresholdPercent-Constants.UGPercent;
expectedMemSize=curMem-u//delta;
#print("CurMem:", curMem, "U:", u, "Delta:", delta, "U/Delta:", u//delta)
expectedMemSize=(0 if expectedMemSize<=0 else expectedMemSize);
cbo.expectedMemSize=expectedMemSize;
scList.append(cbo);
print("Underload: Server "+cbo.sname+" "+cbo.name+" memory",curMem," cur_util: %d decreaseBy: %d"%(curMem,expectedMemSize//Constants.MBtoKB));
scList.sort(key=lambda obj: obj.expectedMemSize, reverse=True)
underList.append(scList);
return underList;
'''
------------------------------------------------
Desc: Over loaded server
-------------------------------------------------
'''
def getOverLoadServer(self,containers):
cp=self.cp;
overList=list();
sla=self.sla;
ofh=open(Monitor.overlogFile,"a");
allfh=open(Monitor.alllogFile,"a");
#sc: server's containers
for sc in containers:
scList=list();
for cbo in sc:
#line to be removed
if (cbo.sname not in sla):
print("~Warning: Server %s is not in SLA."%(cbo.sname ))
continue;
elif(cbo.name not in sla[cbo.sname]):
print("~Warning: Container %s of Server %s is not in SLA."%(cbo.name,cbo.sname ));
continue;
if not(cbo.isRunning()):
print("~Warning: Container %s of Server %s is not RUNNING."%(cbo.name,cbo.sname ))
continue
#checking container is overflow or not
curMem=cbo.getMemoryLimit();
maxMem=self.sla[cbo.sname][cbo.name][1];
if curMem >= maxMem:
continue;
curUtil=cbo.mem_util;
oPercent=curUtil/curMem;
allfh.writelines(str(self.monitorIteration)+"\t"+cbo.sname+"\t"+cbo.name+"\t"+str(curMem)+"\t"+str(curUtil//Constants.MBtoKB)+"\t"+str(oPercent)+"\n");
#print("cbo.name:", cbo.name, "\toPercent:", oPercent)
if(oPercent >= Constants.MemThresholdPercent):
delta=Constants.MemThresholdPercent-Constants.OGPercent;
expectedMemSize=curUtil//delta - curMem;
cbo.expectedMemSize= (expectedMemSize if expectedMemSize+curMem < maxMem else maxMem-curMem);
scList.append(cbo);
print("Overload: Server "+cbo.sname+" "+cbo.name+" memory",curMem," cur_util: %d increaseBy: %d"%(curMem,cbo.expectedMemSize//Constants.MBtoKB));
ofh.writelines(str(self.monitorIteration)+"\t"+cbo.sname+"\t"+cbo.name+"\t"+str(curMem)+"\t"+str(curUtil//Constants.MBtoKB)+"\t"+str(cbo.expectedMemSize//Constants.MBtoKB)+"\n");
scList.sort(key=lambda obj: obj.expectedMemSize, reverse=False)
overList.append(scList);
ofh.close();
allfh.close();
return overList;
def findMachine(self, cpu, memory):
containers = self.server.getAllContainers()
def main():
try:
m = Monitor();
m.run();
except KeyboardInterrupt as e:
print("\nReceived Keyboard Interrupt")
finally:
if Server.SLA != None:
print("Dumping contents of SLA into file")
with open('sla.json', 'w') as f:
dump(Server.SLA, f)
if __name__ == '__main__':
main()