Managing your GIS servers

At version 1.2 the ArcGIS API for Python introduces a new server submodule under the gis.admin module that allows administrators to manage the ArcGIS servers powering their ArcGIS Enterprises. ArcGIS Enterprise includes several software components that are designed to work together. A basic ArcGIS Enterprise deployment can consist of the following:

Refer to ArcGIS Enterprise deployment patterns to learn more about different deployment patterns for ArcGIS Enterprise. No matter which pattern your deployment is, the server module can be used to access and manage it. The diagram below represents the main classes and methods available in the server module

Table of Contents

This non-exhaustive guide covers the following topics

To start with, import the Python API and connect to your GIS as an administrator.

Note: To make use of the server module, you need to connect it using an account with administrative privileges. The server module is only applicable if your GIS is an instance of ArcGIS Enterprise and would not work for ArcGIS Online.
In [3]:
from arcgis.gis import GIS
gis = GIS("https://portalname.domain.com/portal", "username")
Enter password: ········

Accessing the servers behind your GIS

You can get the list of all servers hosted or federated to your Enterprise by calling the list() method from admin.servers object.

In [5]:
gis_servers = gis.admin.servers.list()
gis_servers
Out[5]:
[<Server at https://Dev005223.esri.com:6443/arcgis>]
In [27]:
server1 = gis_servers[0]
type(server1)
Out[27]:
arcgis.gis.server.Server

Once you access your Server object, you can perform operations such as managing data stores, querying logs, accessing services, publishing new services etc. as explained in the rest of this guide

Validate your servers

You can quickly check if your servers are responding to your Enterprise by calling the validate() method. If you get back False, you may need to check one or more of your servers.

In [12]:
gis.admin.servers.validate()
Out[12]:
True

Managing the services on your server

Getting the list of services

One of the important tasks you can perform on a server is monitoring the services running on it and publishing new ones. You can list the services by calling list() method from the Server.services object. By default, you get the services running in root folder.

In [67]:
server1.services.list()
Out[67]:
[<Service at https://python.playground.esri.com/server/admin/services/elevation_270m.ImageServer>,
 <Service at https://python.playground.esri.com/server/admin/services/forest_service.MapServer>,
 <Service at https://python.playground.esri.com/server/admin/services/human_modification_index.ImageServer>,
 <Service at https://python.playground.esri.com/server/admin/services/ImgSrv_Landast_Montana2015.ImageServer>,
 <Service at https://python.playground.esri.com/server/admin/services/SampleWorldCities.MapServer>,
 <Service at https://python.playground.esri.com/server/admin/services/SanDiego_boundary.MapServer>]

To get the services running in a different folder, specify its name as an argument. To get the list of folders on your server, call the folders property

In [16]:
server1.services.folders
Out[16]:
['Hosted', 'System', 'Utilities', '/']

List the services running in Hosted folder

In [18]:
hosted_services = server1.services.list(folder='Hosted')

#print the top 5 as a sample
hosted_services[0:4]
Out[18]:
[<Service at https://python.playground.esri.com/server/admin/services/Hosted/At_Risk_Infrastructure_2017_06_23_10_50_48.FeatureServer>,
 <Service at https://python.playground.esri.com/server/admin/services/Hosted/At_Risk_Infrastructure_2017_06_27_10_26_24.FeatureServer>,
 <Service at https://python.playground.esri.com/server/admin/services/Hosted/At_Risk_Infrastructure_2017_07_07_11_15_57.FeatureServer>,
 <Service at https://python.playground.esri.com/server/admin/services/Hosted/At_Risk_Infrastructure_2017_07_11_10_04_44.FeatureServer>]

Checking if a service exists

To check if a service exists on your server, call the exists() method and specify the folder name, service name and type. You can also use this method to verify if a folder exists on the server.

In [21]:
# check if a FeatureService called 'Ports' exists in Hosted folder
server1.services.exists(folder_name='Hosted', name='Ports', service_type='FeatureServer')
Out[21]:
True

Managing service folders

You can add or remove folders on your server by calling create_folder(), delete_folder().

Note: These folders are different from folders found on user's 'my contents'. To access those folders see ConentManager.create_folder and User.folders
In [22]:
server1.services.create_folder('crime_analysis')
Out[22]:
True

You can delete this folder by calling delete_folder()

In [23]:
server1.services.delete_folder('crime_analysis')
Out[23]:
True

Administering services

If you noticed earlier, calling services.list() returns you a list of Service objects. Using a Service object, you can start, stop, delete, edit, rename and query the properties of a service.

In [26]:
# access the 'SampleWorldCities' service running on root folder
service1 = server1.services.list()[-1]
type(service1)
Out[26]:
arcgis.gis.server.Service

Query the properties property to get details on the service

In [25]:
service1.properties
Out[25]:
{
  "serviceName": "SampleWorldCities",
  "type": "MapServer",
  "description": "The SampleWorldCities service is provided so you can quickly and easily preview the functionality of the GIS server. Click the thumbnail image to open in a web application. This sample service is optional and can be deleted.",
  "capabilities": "Map,Query,Data",
  "provider": "ArcObjects",
  "clusterName": "default",
  "minInstancesPerNode": 1,
  "maxInstancesPerNode": 1,
  "instancesPerContainer": 1,
  "maxWaitTime": 60,
  "maxStartupTime": 300,
  "maxIdleTime": 180,
  "maxUsageTime": 600,
  "loadBalancing": "ROUND_ROBIN",
  "isolationLevel": "HIGH",
  "configuredState": "STARTED",
  "recycleInterval": 24,
  "recycleStartTime": "00:00",
  "keepAliveInterval": -1,
  "private": false,
  "isDefault": false,
  "maxUploadFileSize": 0,
  "allowedUploadFileTypes": "",
  "properties": {
    "useLocalCacheDir": "true",
    "outputDir": "/gisdata/arcgisserver/directories/arcgisoutput",
    "cacheDir": "/gisdata/arcgisserver/directories/arcgiscache",
    "maxScale": "4000",
    "maxRecordCount": "1000",
    "filePath": "${AGSSERVER}/framework/etc/data/WorldCities/WorldCities.msd",
    "supportedImageReturnTypes": "MIME+URL",
    "clientCachingAllowed": "true",
    "isCached": "false",
    "virtualOutputDir": "/rest/directories/arcgisoutput",
    "maxExportTilesCount": "100000",
    "ignoreCache": "false",
    "exportTilesAllowed": "false",
    "cacheOnDemand": "false",
    "minScale": "295000000"
  },
  "portalProperties": {
    "isHosted": false,
    "portalItems": [
      {
        "type": "MapServer",
        "itemID": "0102400090a144259679b6cde45b82b1"
      },
      {
        "type": "WMSServer",
        "itemID": "63250a9efb94447c80c9ca0ad578a4c5"
      }
    ]
  },
  "extensions": [
    {
      "typeName": "WMSServer",
      "capabilities": "GetCapabilities,GetFeatureInfo,GetLegendGraphic,GetMap,GetSchemaExtension,GetStyles",
      "enabled": "true",
      "maxUploadFileSize": 0,
      "allowedUploadFileTypes": "",
      "properties": {
        "name": "SampleWorldCities",
        "title": "WMS"
      }
    },
    {
      "typeName": "KmlServer",
      "capabilities": "SingleImage,SeparateImages,Vectors",
      "enabled": "false",
      "maxUploadFileSize": 0,
      "allowedUploadFileTypes": "",
      "properties": {
        "compatibilityMode": "GoogleEarth",
        "useDefaultSnippets": "true",
        "featureLimit": "1000000",
        "minRefreshPeriod": "30",
        "imageSize": "1024",
        "dpi": "96"
      }
    },
    {
      "typeName": "FeatureServer",
      "capabilities": "Create,Query,Update,Delete,Uploads",
      "enabled": "false",
      "maxUploadFileSize": 0,
      "allowedUploadFileTypes": "",
      "properties": {}
    }
  ],
  "frameworkProperties": {},
  "datasets": []
}

You can also query fine-grained information such as the capabilities enabled on the service

In [27]:
service1.properties.capabilities
Out[27]:
'Map,Query,Data'

You can get the id of one or more Items corresponding to this service on the Enterprise as shown below:

In [29]:
service1.properties.portalProperties.portalItems
Out[29]:
[{
   "type": "MapServer",
   "itemID": "0102400090a144259679b6cde45b82b1"
 }, {
   "type": "WMSServer",
   "itemID": "63250a9efb94447c80c9ca0ad578a4c5"
 }]

Getting status on a service

Calling the status property returns a dictionary with the real time state of the service.

In [30]:
service1.status
Out[30]:
{'configuredState': 'STARTED', 'realTimeState': 'STARTED'}

Starting and stopping a service

Call the start() and stop() methods to start and stop a service.

In [31]:
service1.stop()
Out[31]:
True
In [32]:
#call the status to confirm
service1.status
Out[32]:
{'configuredState': 'STOPPED', 'realTimeState': 'STOPPED'}
In [33]:
#start the service and confirm
service1.start()
service1.status
Out[33]:
{'configuredState': 'STARTED', 'realTimeState': 'STARTED'}

Publishing new services

You can publish new services to your server by calling publish_sd() method from Server.services object.

Note: You need a service definition file to publish a service. You can create SD files using ArcGIS Desktop and Pro. To automate the creation of SD files from your map or project files, refer to ArcPy documentation
In [35]:
server1.services.publish_sd(sd_file_path='/Users/atma6951/Documents/GIS_data/SanDiego_maps.sd',
                            folder=None)
{'name': 'System/CachingControllers', 'type': 'GPServer'}
{'name': 'System/CachingToolsEx', 'type': 'GPServer'}
{'name': 'System/CachingTools', 'type': 'GPServer'}
{'name': 'System/DynamicMappingHost', 'type': 'MapServer'}
{'name': 'System/PublishingToolsEx', 'type': 'GPServer'}
{'name': 'System/PublishingTools', 'type': 'GPServer'}
WARNING 086222: Output directory in service definition is not set or is invalid. Using default output directory.
WARNING 086224: Cache directory in service definition is not set or is invalid. Using default cache directory.
Out[35]:
True

Publishing a service to the server will create an item on the Enterprise. In this case, the service was called 'AGSMS_SD', hence the name of the item.

In [42]:
new_item = gis2.content.search('owner:atma.mani', item_type = 'Map Service')[0]
new_item
Out[42]:
AGSMS_SD
Map Image Layer by atma.mani
Last Modified: August 08, 2017
0 comments, 0 views
In [43]:
new_item.url
Out[43]:
'https://python.playground.esri.com/server/rest/services/AGSMS_SD/MapServer'

Renaming a service

As ArcGIS administrators, you must be familiar that the name of the service forms its URL. You can rename a service, however, this operation should be used carefully since it would break all the layers and maps that refer to this service by its URL

In [45]:
# search for the service
new_service = server1.services.list()[0]
type(new_service)
Out[45]:
arcgis.gis.server.Service

Give this service a descriptive name. Service names cannot contain spaces or special characters.

In [46]:
new_service.rename('SanDiego_boundary')
Out[46]:
True

Renaming will create a new item on the Enterprise corresponding to the new URL

In [58]:
gis2.content.search('owner:atma.mani', 'Map Service')
Out[58]:
[<Item title:"AGSMS_SD" type:Map Image Layer owner:atma.mani>,
 <Item title:"SanDiego_boundary" type:Map Image Layer owner:atma.mani>]

The first Item is now stale and should be deleted by you. The second Item corresponds to the renamed service. You can access and print its url property to verify:

In [59]:
renamed_item = gis2.content.search('owner:atma.mani', 'Map Service')[1]
renamed_item.url
Out[59]:
'https://python.playground.esri.com/server/rest/services/SanDiego_boundary/MapServer'

Thus, you can rename services, or change their URLs using the Python API. You cannot however, use rename() to move a service from one folder into another folder on the server after it is published.

Deleting a service

To delete a service, simply call the delete() method on the Service object.

In [68]:
#Delete the San Diego service. Since it was renamed, you need to search for it
service_list = server1.services.list()
service_list
Out[68]:
[<Service at https://python.playground.esri.com/server/admin/services/elevation_270m.ImageServer>,
 <Service at https://python.playground.esri.com/server/admin/services/forest_service.MapServer>,
 <Service at https://python.playground.esri.com/server/admin/services/human_modification_index.ImageServer>,
 <Service at https://python.playground.esri.com/server/admin/services/ImgSrv_Landast_Montana2015.ImageServer>,
 <Service at https://python.playground.esri.com/server/admin/services/SampleWorldCities.MapServer>,
 <Service at https://python.playground.esri.com/server/admin/services/SanDiego_boundary.MapServer>]
In [69]:
service_list[-1].delete()
Out[69]:
True

Managing server data stores

ArcGIS Data Store is an application that lets you easily configure data storage for hosting and federated servers used with your Enterprise. ArcGIS Data Store provides you with a convenient setup and configuration experience that creates the following different types of data stores.

  • Relational data store -- Stores your portal's hosted feature layer data, including hosted feature layers created as output from spatial analysis tools run in the portal
  • Tile cache data store -- Stores caches for your portal's hosted scene layers
  • Spatiotemporal big data store -— Archives real-time observational data that you can use with an ArcGIS Server running ArcGIS GeoEvent Server that is federated with your portal; also stores the results generated using ArcGIS GeoAnalytics Server tools.

Using the Server.datastores object, you can list, add, remove datastore items as shown below:

Listing the data stores registered with the server

Calling the datastores.list() method returns you a list of Datastore objects.

In [8]:
dstores = server1.datastores.list()
len(dstores)
Out[8]:
3
In [10]:
dstore1 = dstores[0]
type(dstore1)
Out[10]:
arcgis.gis.server.Datastore

Print the path for each of these Datastore objects.

In [13]:
for dstore in dstores:
    print(dstore.properties.path)
/enterpriseDatabases/AGSDataStore_ds_7jq2u67r
/nosqlDatabases/AGSDataStore_bigdata_bds_xjyajz5y
/nosqlDatabases/AGSDataStore_nosqldb_tcs_a6tghhpc

Registering new data stores with the server

You can add or register new data stores with your server by calling the corresponding add method such as add_folder(), add_database(), add_big_data(). To know what types of data stores are supported by your server, query the data_items property:

In [33]:
server1.datastores.data_items
Out[33]:
{'rootItems': ['/bigDataFileShares',
  '/cloudStores',
  '/enterpriseDatabases',
  '/fileShares',
  '/nosqlDatabases',
  '/rasterStores']}

Add a folder data store

In [25]:
ca_datastore = server1.datastores.add_folder(name='CA_earthquakes', 
                              server_path='\\teton\atma_shared\datasets\californiapoints')
ca_datastore
Out[25]:
<Datastore title:"https://Dev005223.esri.com:6443/arcgis/admin/data/items/fileShares/CA_earthquakes" type:"folder">
In [34]:
type(ca_datastore)
Out[34]:
arcgis._impl._server.admin._data.Datastore

The add_folder() method returns you a Datastore object. This object can be used to inspect, modify or delete / unregister that data store entry. You can inspect the properties of the data store by querying the properties property.

In [36]:
ca_datastore.properties
Out[36]:
{
  "path": "/fileShares/CA_earthquakes",
  "type": "folder",
  "id": "53c50994-9b2b-4cf2-bcfd-a59651cea8ed",
  "info": {
    "path": "\\teton\u0007tma_shared\\datasets\\californiapoints",
    "dataStoreConnectionType": "shared"
  }
}

Validating data stores

You can validate the data store registered with your server to ensure your server can continue to access them.

In [35]:
ca_datastore.validate()
Out[35]:
True

You can validate all the data stores by calling the validate() method from the Server.datastores object

In [41]:
server1.datastores.validate()
Out[41]:
True

Removing data store entries

To remove a data store, simply call the delete() method from the corresponding Datastore object:

In [42]:
ca_datastore.delete()
Out[42]:
True

Querying server logs

ArcGIS Server records events that occur, and any errors associated with those events, to logs. Logs are an important tool for monitoring and troubleshooting problems with your site. Information in the logs will help you identify errors and provide context on how to address problems. Refer about server logs to learn more about your ArcGIS Server logs, setting different logging levels etc.

You can access a server's logs using the logs property of the Server object.

In [43]:
server1.logs.settings
Out[43]:
{'logDir': 'C:\\arcgisserver/logs\\',
 'logLevel': 'WARNING',
 'maxErrorReportsCount': 10,
 'maxLogFileAge': 90,
 'statisticsConfig': {'enabled': True,
  'maxHistory': 0,
  'samplingInterval': 30,
  'statisticsDir': 'C:\\arcgisserver\\directories\\arcgissystem'},
 'usageMeteringEnabled': False}

Filtering and querying server logs

Using the query() method, you can filter and search for server logs. Refer to the query API ref doc for all the arguments supported. In the example below, logs for the previous 10 days is searched.

In [47]:
import datetime
import pandas as pd
now = datetime.datetime.now()
start_time = now - datetime.timedelta(days=10)
start_time
Out[47]:
datetime.datetime(2017, 7, 30, 15, 29, 4, 144692)

You can pass a Python Datetime object to the time arguments.

In [50]:
recent_logs = server1.logs.query(start_time = start_time)

#print a message as a sample
recent_logs['logMessages'][0]
Out[50]:
{'code': 6602,
 'elapsed': '',
 'machine': 'DEV005223.ESRI.COM',
 'message': "Failed to return the service configuration 'Utilities/PrintingTools.GPServer'. Server machine 'https://DEV005223.ESRI.COM:7443/arcgis/sharing/rest/content/items/430b49a241bd418aaf476d7e5a64fdb9' returned an error. 'Item does not exist or is inaccessible.'",
 'methodName': '',
 'process': '5660',
 'source': 'Admin',
 'thread': '14',
 'time': 1499634940286,
 'type': 'SEVERE',
 'user': ''}

You can construct a Pandas DataFrame from the query result and visualize the logs as a table:

In [51]:
log_df = pd.DataFrame.from_records(recent_logs)
log_df.head(5) #display the first 5 records
Out[51]:
endTime hasMore logMessages startTime
0 1497908616688 False {'type': 'SEVERE', 'message': 'Failed to retur... 1499634940286
1 1497908616688 False {'type': 'SEVERE', 'message': 'Unable to conne... 1499634940286
2 1497908616688 False {'type': 'SEVERE', 'message': 'Unable to conne... 1499634940286
3 1497908616688 False {'type': 'SEVERE', 'message': 'Unable to conne... 1499634940286
4 1497908616688 False {'type': 'SEVERE', 'message': 'Unable to conne... 1499634940286

You can quickly check for errors reports as shown below:

In [57]:
server1.logs.count_error_reports()
Out[57]:
{'machineName': 'DEV005223.ESRI.COM', 'reportCount': 0}

Monitoring server usage

ArcGIS Server records various service statistics, such as total requests, average response time and timeouts. Administrators and publishers can use this information to monitor service activity to better understand how clients are using services. For example, monitoring server statistics help you answer questions such as:

  • What is the total number of requests that my ArcGIS Server site handled during the past week?
  • How was the service request load distributed during the past month?
  • How are my services performing on an hourly basis?
  • What was the maximum number of service instances used at any given time for a particular service?

To learn more about this, refer to about server statistics help page. To access this information, use the Server.usage property:

In [71]:
server1.usage.settings
Out[71]:
{'enabled': True,
 'maxHistory': 0,
 'samplingInterval': 30,
 'statisticsDir': 'C:\\arcgisserver\\directories\\arcgissystem'}

Using built-in reports

By default, when you install ArcGIS Server, you get three pre-configured reports. These reports are based on services that are already running on your server. You can access these and any new reports you create by querying the list() method.

In [88]:
usage_reports = server1.usage.list()
usage_reports
Out[88]:
[<arcgis.gis.server.Report at 0x110a3f860>,
 <arcgis.gis.server.Report at 0x110a3f908>,
 <arcgis.gis.server.Report at 0x110a3f470>]

You get back a list of Report objects. Print the names of the reports:

In [73]:
for r in usage_reports:
    print(r.properties['reportname'])
Max response times for the last 7 days
Timed-out requests for the last 7 days
Total requests for the last 7 days

Querying maximum reponse times for the last 7 days

In [89]:
max_resp_report = usage_reports[0]

#Run the query
data = max_resp_report.query()

#display the keys in the report query response
data['report'].keys()
Out[89]:
dict_keys(['reportname', 'metadata', 'time-slices', 'report-data'])

Plot the response time in a bar chart

In [76]:
from datetime import datetime
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
%matplotlib inline
In [108]:
#store reponse times in Y axis
data_y = data['report']['report-data'][0][0]['data']

#convert dates to readable dates and store in X axis
data_x = [pd.to_datetime(datetime.fromtimestamp(d//1000)) \
          for d in data['report']['time-slices']]

df = pd.DataFrame(list(zip(data_x, data_y)), columns=["date", "count"])
q = df['count'].isnull() # change NaN values to 0
df.loc[q, 'count'] = 0
df.index = df['date']
df['count'] = df['count'] 

ax = df.plot(kind='bar', x=df['date'])
ticklabels = ['']*len(df.index)
ticklabels[::4] = [item.strftime('%b %d') for item in df.index[::4]]
ax.xaxis.set_major_formatter(ticker.FixedFormatter(ticklabels))
ax.set_title('Maximum reponse time in the last 7 days')
ax.set_ylabel('Time in seconds')
plt.gcf().autofmt_xdate()
plt.show()

Creating Quick Reports

Quick reports are useful for administrators who want to get a one-shot set of data. This information is generated on the fly on ArcGIS Server, and allows for report generation for services or server information that may not be monitored all the time.

Note: On the fly reports that are deleted right after data is returned

The quick report supports various time spans:

  • LAST_DAY - 24 hours from your current time
  • LAST_WEEK - 7 days from your current date
  • LAST_MONTH - 31 days from your current date
  • LAST_YEAR - 365 days from your current date

Reporting Queries are made by specifying the resource you want to monitor. For example, administrators who want to monitor a specific folder, HOSTED, would set the query to: services/Hosted. The default is to monitor all services.

Quick report metrics are:

  • RequestCount - the number of requests received
  • RequestsFailed - the number of requests that failed
  • RequestsTimedOut - the number of requests that timed out
  • RequestMaxResponseTime - the maximum response time
  • RequestAvgResponseTime - the average response time
  • ServiceActiveInstances - the maximum number of active (running) service instances sampled at 1 minute intervals, for a specified service

Get the total number of requests in the last 1 year

In [120]:
data = server1.usage.quick_report(since="LAST_MONTH", metrics="RequestCount")
data['report'].keys()
Out[120]:
dict_keys(['reportname', 'metadata', 'time-slices', 'report-data'])

Plot the results in a bar chart

In [121]:
#store reponse times in Y axis
data_y = data['report']['report-data'][0][0]['data']

#convert dates to readable dates and store in X axis
data_x = [pd.to_datetime(datetime.fromtimestamp(d//1000)) \
          for d in data['report']['time-slices']]

#create a Pandas DataFrame from the report
df = pd.DataFrame(list(zip(data_x, data_y)), columns=["date", "count"])
q = df['count'].isnull() # change NaN values to 0
df.loc[q, 'count'] = 0
df.index = df['date']
df['count'] = df['count'] 

#plot as a bar chart
ax = df.plot(kind='bar', x=df['date'])
ticklabels = ['']*len(df.index)
ticklabels[::4] = [item.strftime('%b %d') for item in df.index[::4]]
ax.xaxis.set_major_formatter(ticker.FixedFormatter(ticklabels))
plt.gcf().autofmt_xdate()
plt.show()

Accessing the machines powering your servers

You can access the machines powering your GIS servers using the Server.machines property. By calling the list() method, you get back a list of Machine objects:

In [122]:
machine_list = server1.machines.list()
machine_list
Out[122]:
[<Machine at https://python.playground.esri.com/server/admin/machines/10.0.0.250>]

Access the properties of a machine using properties.

In [125]:
m1 = machine_list[0]
m1.properties
{
  "machineName": "DEV005223.ESRI.COM",
  "platform": "Windows Server 2012 R2-amd64-6.3",
  "ports": {
    "OpenEJBPort": 4000,
    "JMXPort": 4001,
    "NamingPort": 4002,
    "DerbyPort": 4003,
    "tcpClusterPort": 4004,
    "HTTP": 6080,
    "webSocketsPort": 6180,
    "HTTPS": 6443
  },
  "ServerStartTime": 1498283009444,
  "webServerMaxHeapSize": -1,
  "appServerMaxHeapSize": 256,
  "socMaxHeapSize": 64,
  "webServerSSLEnabled": true,
  "webServerCertificateAlias": "SelfSignedCertificate",
  "adminURL": "https://Dev005223.esri.com:6443/arcgis/admin",
  "configuredState": "STARTED",
  "synchronize": false
}

Use the status property to verify the state of your machine.

In [126]:
m1.status
Out[126]:
{'configuredState': 'STARTED', 'realTimeState': 'STARTED'}

Get the list of SSL certificates:

In [127]:
m1.ssl_certificates
Out[127]:
{'certificates': ['selfsignedcertificate']}

Download existing certificates or import new ones to your server using the appropriate methods:

In [129]:
m1.export_certificate(m1.ssl_certificates['certificates'][0])
Out[129]:
'/var/folders/48/f8q226cx6wn8h5t8xkv5y7rhj1s2w8/T/SelfSignedCertificate.cer'

Monitoring your server licenses and system settings

Accessing system directories

Calling the directories property of Server.system returns you back a list of Directory objects.

In [138]:
all_dir = server1.system.directories.all
all_dir[0]
Out[138]:
ServerDirectory({"name": "arcgiscache", "physicalPath": "C:\\arcgisserver\\directories\\arcgiscache", "directoryType": "CACHE", "cleanupMode": "NONE", "maxFileAge": 0, "description": "Stores tile caches used by map, globe, and image services for rapid performance.", "useLocalDir": "false", "localDirectoryPath": "", "virtualPath": "/rest/directories/arcgiscache"})

Print the name and path on disk for each of these server directories:

In [144]:
for fld in all_dir:
    print(fld.properties.name + " : " + fld.properties.physicalPath)
arcgiscache : C:\arcgisserver\directories\arcgiscache
arcgisindex : C:\arcgisserver\directories\arcgissystem\arcgisindex
arcgisinput : C:\arcgisserver\directories\arcgissystem\arcgisinput
arcgisjobregistry : C:\arcgisserver\directories\arcgissystem\arcgisjobregistry
arcgisjobs : C:\arcgisserver\directories\arcgisjobs
arcgisoutput : C:\arcgisserver\directories\arcgisoutput
arcgisuploads : C:\arcgisserver\directories\arcgissystem\arcgisuploads
kml : C:\arcgisserver\directories\arcgissystem\kml
arcgissystem : C:\arcgisserver\directories\arcgissystem

By calling the clean() and edit() methods on a Directory object, you can clean the contents or designate a different directory path for the server.

Monitoring server licenses and extensions

Use the licenses property of Server.system object to get a dictionary of various licenses and extensions available on the server.

In [150]:
server1.system.licenses.keys()
Out[150]:
dict_keys(['edition', 'level', 'datafeature', 'extensions', 'features'])

Find the license level of the current server:

In [173]:
server1.system.licenses['edition']
Out[173]:
{'canExpire': True,
 'expiration': 1508223600000,
 'featureName': 'esriServerLicenseAdvanced',
 'name': 'svradvanced',
 'version': '10.5'}

Print all the extensions and their expiration:

In [189]:
from datetime import datetime

for extn in server1.system.licenses['features']:
    #convert expiration to a readable format
    d = datetime.fromtimestamp(int(extn['expiration']/1000))
    
    print("{:50s} {}".format(extn['displayName'], d.isoformat()))
ArcGIS Server Advanced Core                        2017-10-17T00:00:00
SDE Enterprise Core                                2017-10-17T00:00:00
ArcGIS Aviation: Airports for Server               2017-10-17T00:00:00
Workflow Manager Extension for ArcGIS Server       2017-10-17T00:00:00
ArcGIS Aviation: Charting for Server               2017-10-17T00:00:00
Business Analyst Extension for ArcGIS Server       2017-10-17T00:00:00
ArcGIS for INSPIRE                                 2017-10-17T00:00:00
ArcGIS Maritime: Charting for Server               2017-10-17T00:00:00
Location Referencing for Server                    2017-10-17T00:00:00
ArcGIS Data Reviewer Server                        2017-10-17T00:00:00
Esri Roads and Highways for ArcGIS Server          2017-10-17T00:00:00
ArcGIS Maritime: Bathymetry for Server             2017-10-17T00:00:00
Esri Defense Mapping for Server                    2017-10-17T00:00:00
ArcGIS Server Enterprise                           2017-10-17T00:00:00
Esri Production Mapping for Server                 2017-10-17T00:00:00
Data Interoperability Extension for ArcGIS Server  2017-10-17T00:00:00
Network Analyst Extension for ArcGIS Server        2017-10-17T00:00:00
Roadway Reporter for Esri Roads and Highways       2017-10-17T00:00:00

Feedback on this topic?