Advertisement
Guest User

Untitled

a guest
Sep 10th, 2016
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.19 KB | None | 0 0
  1. #!/usr/bin/python
  2. import requests
  3. import json
  4. import math
  5. import time
  6. import datetime
  7.  
  8. marathonAddress = ''
  9. influxdbAddress = ''
  10. influxdbUsername = ''
  11. influxdbPassword = ''
  12. influxdbDatabase = ''
  13.  
  14. # Example env variables to include in app
  15. # "autoscale": "true"
  16. # "autoscale_min_instances": "2"
  17. # "autoscale_max_instances": "8"
  18. # "autoscale_rule_memory": "memory_usage | value | target | 1000 | 180 | 120"
  19. # where:
  20. # memory = rule name
  21. # memory_usage = InfluxDB measurement
  22. # value = InfluxDB field
  23. # target = specifies that this rule defines a target value
  24. # 1000 = target value averaged across all instances
  25. # 180 = time period to check for target value
  26. # 120 = backoff time after scaling
  27. #
  28. # Example threshold rule [not yet implemented]:
  29. # "autoscale_rule_memory1": "memory_usage | value | threshold | > | 1000 | 180 | 120"
  30. # where:
  31. # memory1 = rule name
  32. # memory_usage = InfluxDB measurement
  33. # value = InfluxDB field
  34. # > = operator (can be < or > or <= or >=)
  35. # 1000 = threshold value
  36. # 180 = time period to check for threshold value
  37. # 120 = backoff time after scaling
  38.  
  39. events = {}
  40.  
  41. # Check all apps and apply scaling if necessary to apps which have autoscaling enabled
  42. def get_apps():
  43. response=requests.get(marathonAddress + '/v2/apps').json()
  44. for app in response['apps']:
  45. if 'autoscale' in app['env']:
  46. if app['env']['autoscale'] == 'true':
  47. minInstances = int(app['env']['autoscale_min_instances'])
  48. maxInstances = int(app['env']['autoscale_max_instances'])
  49. for env in app['env']:
  50. if 'autoscale_rule' in env:
  51. name = env.replace('autoscale_rule_','')
  52. apply_scale_rule(name, app['id'], minInstances, maxInstances, app['env'][env])
  53.  
  54. # Apply autoscale rule
  55. def apply_scale_rule(name, app, minInstances, maxInstances, rule):
  56. rule = rule.replace(" ", "").split("|")
  57.  
  58. currentInstances = get_app(app)
  59. dbMeasurement = rule[0]
  60. dbValue = rule[1]
  61. if rule[2] == 'target':
  62. target = int(rule[3])
  63. trigger = rule[4]
  64. backoff = int(rule[5])
  65.  
  66. currentValue = query_db(dbMeasurement, dbValue, app, trigger)
  67. ideal = int(round(currentValue/target))
  68.  
  69. if ideal < minInstances:
  70. ideal = minInstances
  71. if ideal > maxInstances:
  72. ideal = maxInstances
  73.  
  74. if app not in events:
  75. events[app] = 0
  76.  
  77. if currentInstances != ideal and time.time() - events[app] > backoff:
  78. print ' ',app,': Scaling to',ideal,'instances from',currentInstances,'instances','due to target from rule',name,'( target=',target,'current=',currentValue,')'
  79. events[app] = time.time()
  80. scale_app(app, ideal)
  81.  
  82. # Query InfluxDB
  83. def query_db(measurement, value, app, trigger):
  84. appName = gen_name(app)
  85. query = "query?db=" + influxdbDatabase + "&q=SELECT MEAN(" + value + ") FROM " + measurement + " WHERE app = '" + appName + "' AND time > now() - " + trigger + "s fill(0)"
  86. r = requests.get(influxdbAddress + '/' + query, auth=(influxdbUsername, influxdbPassword))
  87. data = r.json()
  88. results = data['results']
  89. return results[0]['series'][0]['values'][0][1]
  90.  
  91. # Generate application name to be consistent with task name
  92. # (app name in InfluxDB is based on the task name)
  93. def gen_name(app):
  94. app = app.split('/')
  95. if len(app) > 2:
  96. app = app[2] + '.' + app[1]
  97. else:
  98. app = app[1]
  99. return app
  100.  
  101. # Get current number of instances
  102. def get_app(marathon_app):
  103. response=requests.get(marathonAddress + '/v2/apps/'+ marathon_app).json()
  104. app_instances=response['app']['instances']
  105. return app_instances
  106.  
  107. # Scale application
  108. def scale_app(marathon_app, instances):
  109. data = {'instances': instances}
  110. json_data = json.dumps(data)
  111. headers = {'Content-type': 'application/json'}
  112. response = requests.put(marathonAddress + '/v2/apps/'+ marathon_app,json_data,headers=headers)
  113.  
  114. if __name__ == "__main__":
  115. while 1 == 1:
  116. print datetime.datetime.now(),'Checking apps'
  117. get_apps()
  118. time.sleep(60)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement