|
7 | 7 |
|
8 | 8 |
|
9 | 9 | from datetime import datetime
|
10 |
| -from typing import Any, List, Optional, Sequence, TypeVar, cast |
| 10 | +from typing import Any, Dict, List, Optional, Sequence, TypeVar, cast |
11 | 11 | from warnings import warn
|
12 | 12 |
|
13 | 13 | from arangoasync.aql import AQL
|
|
42 | 42 | PermissionListError,
|
43 | 43 | PermissionResetError,
|
44 | 44 | PermissionUpdateError,
|
| 45 | + ServerApiCallsError, |
45 | 46 | ServerAvailableOptionsGetError,
|
46 | 47 | ServerCheckAvailabilityError,
|
47 | 48 | ServerCurrentOptionsGetError,
|
|
51 | 52 | ServerExecuteError,
|
52 | 53 | ServerLicenseGetError,
|
53 | 54 | ServerLicenseSetError,
|
| 55 | + ServerLogLevelError, |
| 56 | + ServerLogLevelResetError, |
| 57 | + ServerLogLevelSetError, |
| 58 | + ServerLogSettingError, |
| 59 | + ServerLogSettingSetError, |
| 60 | + ServerMetricsError, |
54 | 61 | ServerModeError,
|
55 | 62 | ServerModeSetError,
|
| 63 | + ServerReadLogError, |
56 | 64 | ServerReloadRoutingError,
|
57 | 65 | ServerShutdownError,
|
58 | 66 | ServerShutdownProgressError,
|
@@ -2876,6 +2884,339 @@ def response_handler(resp: Response) -> Response:
|
2876 | 2884 |
|
2877 | 2885 | return await self._executor.execute(request, response_handler)
|
2878 | 2886 |
|
| 2887 | + async def metrics(self, server_id: Optional[str] = None) -> Result[str]: |
| 2888 | + """Return server metrics in Prometheus format. |
| 2889 | +
|
| 2890 | + Args: |
| 2891 | + server_id (str | None): Returns metrics of the specified server. |
| 2892 | + If no serverId is given, the asked server will reply. |
| 2893 | +
|
| 2894 | + Returns: |
| 2895 | + str: Server metrics in Prometheus format. |
| 2896 | +
|
| 2897 | + Raises: |
| 2898 | + ServerMetricsError: If the operation fails. |
| 2899 | +
|
| 2900 | + References: |
| 2901 | + - `metrics-api-v2 <https://docs.arangodb.com/stable/develop/http-api/monitoring/metrics/#metrics-api-v2>`__ |
| 2902 | + """ # noqa: E501 |
| 2903 | + params: Params = {} |
| 2904 | + if server_id is not None: |
| 2905 | + params["serverId"] = server_id |
| 2906 | + |
| 2907 | + request = Request( |
| 2908 | + method=Method.GET, |
| 2909 | + endpoint="/_admin/metrics/v2", |
| 2910 | + params=params, |
| 2911 | + ) |
| 2912 | + |
| 2913 | + def response_handler(resp: Response) -> str: |
| 2914 | + if not resp.is_success: |
| 2915 | + raise ServerMetricsError(resp, request) |
| 2916 | + return resp.raw_body.decode("utf-8") |
| 2917 | + |
| 2918 | + return await self._executor.execute(request, response_handler) |
| 2919 | + |
| 2920 | + async def read_log_entries( |
| 2921 | + self, |
| 2922 | + upto: Optional[int | str] = None, |
| 2923 | + level: Optional[str] = None, |
| 2924 | + start: Optional[int] = None, |
| 2925 | + size: Optional[int] = None, |
| 2926 | + offset: Optional[int] = None, |
| 2927 | + search: Optional[str] = None, |
| 2928 | + sort: Optional[str] = None, |
| 2929 | + server_id: Optional[str] = None, |
| 2930 | + ) -> Result[Json]: |
| 2931 | + """Read the global log from server. |
| 2932 | +
|
| 2933 | + Args: |
| 2934 | + upto (int | str | None): Return the log entries up to the given level |
| 2935 | + (mutually exclusive with parameter **level**). Allowed values are |
| 2936 | + "fatal", "error", "warning", "info" (default), "debug" and "trace". |
| 2937 | + level (int | str | None): Return the log entries of only the given level |
| 2938 | + (mutually exclusive with **upto**). |
| 2939 | + start (int | None): Return the log entries whose ID is greater or equal to |
| 2940 | + the given value. |
| 2941 | + size (int | None): Restrict the size of the result to the given value. |
| 2942 | + This can be used for pagination. |
| 2943 | + offset (int | None): Number of entries to skip (e.g. for pagination). |
| 2944 | + search (str | None): Return only the log entries containing the given text. |
| 2945 | + sort (str | None): Sort the log entries according to the given fashion, |
| 2946 | + which can be "sort" or "desc". |
| 2947 | + server_id (str | None): Returns all log entries of the specified server. |
| 2948 | + If no serverId is given, the asked server will reply. |
| 2949 | +
|
| 2950 | + Returns: |
| 2951 | + dict: Server log entries. |
| 2952 | +
|
| 2953 | + Raises: |
| 2954 | + ServerReadLogError: If the operation fails. |
| 2955 | +
|
| 2956 | + References: |
| 2957 | + - `get-the-global-server-logs <https://docs.arangodb.com/stable/develop/http-api/monitoring/logs/#get-the-global-server-logs>`__ |
| 2958 | + """ # noqa: E501 |
| 2959 | + params: Params = {} |
| 2960 | + if upto is not None: |
| 2961 | + params["upto"] = upto |
| 2962 | + if level is not None: |
| 2963 | + params["level"] = level |
| 2964 | + if start is not None: |
| 2965 | + params["start"] = start |
| 2966 | + if size is not None: |
| 2967 | + params["size"] = size |
| 2968 | + if offset is not None: |
| 2969 | + params["offset"] = offset |
| 2970 | + if search is not None: |
| 2971 | + params["search"] = search |
| 2972 | + if sort is not None: |
| 2973 | + params["sort"] = sort |
| 2974 | + if server_id is not None: |
| 2975 | + params["serverId"] = server_id |
| 2976 | + |
| 2977 | + request = Request( |
| 2978 | + method=Method.GET, |
| 2979 | + endpoint="/_admin/log/entries", |
| 2980 | + params=params, |
| 2981 | + prefix_needed=False, |
| 2982 | + ) |
| 2983 | + |
| 2984 | + def response_handler(resp: Response) -> Json: |
| 2985 | + if not resp.is_success: |
| 2986 | + raise ServerReadLogError(resp, request) |
| 2987 | + |
| 2988 | + result: Json = self.deserializer.loads(resp.raw_body) |
| 2989 | + return result |
| 2990 | + |
| 2991 | + return await self._executor.execute(request, response_handler) |
| 2992 | + |
| 2993 | + async def log_levels( |
| 2994 | + self, server_id: Optional[str] = None, with_appenders: Optional[bool] = None |
| 2995 | + ) -> Result[Json]: |
| 2996 | + """Return current logging levels. |
| 2997 | +
|
| 2998 | + Args: |
| 2999 | + server_id (str | None): Forward the request to the specified server. |
| 3000 | + with_appenders (bool | None): Include appenders in the response. |
| 3001 | +
|
| 3002 | + Returns: |
| 3003 | + dict: Current logging levels. |
| 3004 | +
|
| 3005 | + Raises: |
| 3006 | + ServerLogLevelError: If the operation fails. |
| 3007 | +
|
| 3008 | + References: |
| 3009 | + - `get-the-server-log-levels <https://docs.arangodb.com/stable/develop/http-api/monitoring/logs/#get-the-server-log-levels>`__ |
| 3010 | + """ # noqa: E501 |
| 3011 | + params: Params = {} |
| 3012 | + if server_id is not None: |
| 3013 | + params["serverId"] = server_id |
| 3014 | + if with_appenders is not None: |
| 3015 | + params["withAppenders"] = with_appenders |
| 3016 | + |
| 3017 | + request = Request( |
| 3018 | + method=Method.GET, |
| 3019 | + endpoint="/_admin/log/level", |
| 3020 | + params=params, |
| 3021 | + prefix_needed=False, |
| 3022 | + ) |
| 3023 | + |
| 3024 | + def response_handler(resp: Response) -> Json: |
| 3025 | + if not resp.is_success: |
| 3026 | + raise ServerLogLevelError(resp, request) |
| 3027 | + result: Json = self.deserializer.loads(resp.raw_body) |
| 3028 | + return result |
| 3029 | + |
| 3030 | + return await self._executor.execute(request, response_handler) |
| 3031 | + |
| 3032 | + async def set_log_levels( |
| 3033 | + self, |
| 3034 | + server_id: Optional[str] = None, |
| 3035 | + with_appenders: Optional[bool] = None, |
| 3036 | + **kwargs: Dict[str, Any], |
| 3037 | + ) -> Result[Json]: |
| 3038 | + """Set the logging levels. |
| 3039 | +
|
| 3040 | + This method takes arbitrary keyword arguments where the keys are the |
| 3041 | + logger names and the values are the logging levels. For example: |
| 3042 | +
|
| 3043 | + .. code-block:: python |
| 3044 | +
|
| 3045 | + db.set_log_levels( |
| 3046 | + agency='DEBUG', |
| 3047 | + collector='INFO', |
| 3048 | + threads='WARNING' |
| 3049 | + ) |
| 3050 | +
|
| 3051 | + Keys that are not valid logger names are ignored. |
| 3052 | +
|
| 3053 | + Args: |
| 3054 | + server_id (str | None) -> Forward the request to a specific server. |
| 3055 | + with_appenders (bool | None): Include appenders in the response. |
| 3056 | + kwargs (dict): Logging levels to be set. |
| 3057 | +
|
| 3058 | + Returns: |
| 3059 | + dict: New logging levels. |
| 3060 | +
|
| 3061 | + Raises: |
| 3062 | + ServerLogLevelSetError: If the operation fails. |
| 3063 | +
|
| 3064 | + References: |
| 3065 | + - `set-the-structured-log-settings <https://docs.arangodb.com/stable/develop/http-api/monitoring/logs/#set-the-structured-log-settings>`__ |
| 3066 | + """ # noqa: E501 |
| 3067 | + params: Params = {} |
| 3068 | + if server_id is not None: |
| 3069 | + params["serverId"] = server_id |
| 3070 | + if with_appenders is not None: |
| 3071 | + params["withAppenders"] = with_appenders |
| 3072 | + |
| 3073 | + request = Request( |
| 3074 | + method=Method.PUT, |
| 3075 | + endpoint="/_admin/log/level", |
| 3076 | + params=params, |
| 3077 | + data=self.serializer.dumps(kwargs), |
| 3078 | + prefix_needed=False, |
| 3079 | + ) |
| 3080 | + |
| 3081 | + def response_handler(resp: Response) -> Json: |
| 3082 | + if not resp.is_success: |
| 3083 | + raise ServerLogLevelSetError(resp, request) |
| 3084 | + result: Json = self.deserializer.loads(resp.raw_body) |
| 3085 | + return result |
| 3086 | + |
| 3087 | + return await self._executor.execute(request, response_handler) |
| 3088 | + |
| 3089 | + async def reset_log_levels(self, server_id: Optional[str] = None) -> Result[Json]: |
| 3090 | + """Reset the logging levels. |
| 3091 | +
|
| 3092 | + Revert the server’s log level settings to the values they had at startup, |
| 3093 | + as determined by the startup options specified on the command-line, |
| 3094 | + a configuration file, and the factory defaults. |
| 3095 | +
|
| 3096 | + Args: |
| 3097 | + server_id: Forward the request to a specific server. |
| 3098 | +
|
| 3099 | + Returns: |
| 3100 | + dict: New logging levels. |
| 3101 | +
|
| 3102 | + Raises: |
| 3103 | + ServerLogLevelResetError: If the operation fails. |
| 3104 | +
|
| 3105 | + References: |
| 3106 | + - `reset-the-server-log-levels <https://docs.arangodb.com/stable/develop/http-api/monitoring/logs/#reset-the-server-log-levels>`__ |
| 3107 | + """ # noqa: E501 |
| 3108 | + params: Params = {} |
| 3109 | + if server_id is not None: |
| 3110 | + params["serverId"] = server_id |
| 3111 | + |
| 3112 | + request = Request( |
| 3113 | + method=Method.DELETE, |
| 3114 | + endpoint="/_admin/log/level", |
| 3115 | + params=params, |
| 3116 | + prefix_needed=False, |
| 3117 | + ) |
| 3118 | + |
| 3119 | + def response_handler(resp: Response) -> Json: |
| 3120 | + if not resp.is_success: |
| 3121 | + raise ServerLogLevelResetError(resp, request) |
| 3122 | + result: Json = self.deserializer.loads(resp.raw_body) |
| 3123 | + return result |
| 3124 | + |
| 3125 | + return await self._executor.execute(request, response_handler) |
| 3126 | + |
| 3127 | + async def log_settings(self) -> Result[Json]: |
| 3128 | + """Get the structured log settings. |
| 3129 | +
|
| 3130 | + Returns: |
| 3131 | + dict: Current structured log settings. |
| 3132 | +
|
| 3133 | + Raises: |
| 3134 | + ServerLogSettingError: If the operation fails. |
| 3135 | +
|
| 3136 | + References: |
| 3137 | + - `get-the-structured-log-settings <https://docs.arangodb.com/stable/develop/http-api/monitoring/logs/#get-the-structured-log-settings>`__ |
| 3138 | + """ # noqa: E501 |
| 3139 | + request = Request( |
| 3140 | + method=Method.GET, |
| 3141 | + endpoint="/_admin/log/structured", |
| 3142 | + prefix_needed=False, |
| 3143 | + ) |
| 3144 | + |
| 3145 | + def response_handler(resp: Response) -> Json: |
| 3146 | + if not resp.is_success: |
| 3147 | + raise ServerLogSettingError(resp, request) |
| 3148 | + result: Json = self.deserializer.loads(resp.raw_body) |
| 3149 | + return result |
| 3150 | + |
| 3151 | + return await self._executor.execute(request, response_handler) |
| 3152 | + |
| 3153 | + async def set_log_settings(self, **kwargs: Dict[str, Any]) -> Result[Json]: |
| 3154 | + """Set the structured log settings. |
| 3155 | +
|
| 3156 | + This method takes arbitrary keyword arguments where the keys are the |
| 3157 | + structured log parameters and the values are true or false, for either |
| 3158 | + enabling or disabling the parameters. |
| 3159 | +
|
| 3160 | + .. code-block:: python |
| 3161 | +
|
| 3162 | + db.set_log_settings( |
| 3163 | + database=True, |
| 3164 | + url=True, |
| 3165 | + username=False, |
| 3166 | + ) |
| 3167 | +
|
| 3168 | + Args: |
| 3169 | + kwargs (dict): Structured log parameters to be set. |
| 3170 | +
|
| 3171 | + Returns: |
| 3172 | + dict: New structured log settings. |
| 3173 | +
|
| 3174 | + Raises: |
| 3175 | + ServerLogSettingSetError: If the operation fails. |
| 3176 | +
|
| 3177 | + References: |
| 3178 | + - `set-the-structured-log-settings <https://docs.arangodb.com/stable/develop/http-api/monitoring/logs/#set-the-structured-log-settings>`__ |
| 3179 | + """ # noqa: E501 |
| 3180 | + request = Request( |
| 3181 | + method=Method.PUT, |
| 3182 | + endpoint="/_admin/log/structured", |
| 3183 | + data=self.serializer.dumps(kwargs), |
| 3184 | + prefix_needed=False, |
| 3185 | + ) |
| 3186 | + |
| 3187 | + def response_handler(resp: Response) -> Json: |
| 3188 | + if not resp.is_success: |
| 3189 | + raise ServerLogSettingSetError(resp, request) |
| 3190 | + result: Json = self.deserializer.loads(resp.raw_body) |
| 3191 | + return result |
| 3192 | + |
| 3193 | + return await self._executor.execute(request, response_handler) |
| 3194 | + |
| 3195 | + async def api_calls(self) -> Result[Json]: |
| 3196 | + """Get a list of the most recent requests with a timestamp and the endpoint. |
| 3197 | +
|
| 3198 | + Returns: |
| 3199 | + dict: API calls made to the server. |
| 3200 | +
|
| 3201 | + Raises: |
| 3202 | + ServerApiCallsError: If the operation fails. |
| 3203 | +
|
| 3204 | + References: |
| 3205 | + - `get-recent-api-calls <https://docs.arangodb.com/stable/develop/http-api/monitoring/api-calls/#get-recent-api-calls>`__ |
| 3206 | + """ # noqa: E501 |
| 3207 | + request = Request( |
| 3208 | + method=Method.GET, |
| 3209 | + endpoint="/_admin/server/api-calls", |
| 3210 | + ) |
| 3211 | + |
| 3212 | + def response_handler(resp: Response) -> Json: |
| 3213 | + if not resp.is_success: |
| 3214 | + raise ServerApiCallsError(resp, request) |
| 3215 | + result: Json = self.deserializer.loads(resp.raw_body)["result"] |
| 3216 | + return result |
| 3217 | + |
| 3218 | + return await self._executor.execute(request, response_handler) |
| 3219 | + |
2879 | 3220 |
|
2880 | 3221 | class StandardDatabase(Database):
|
2881 | 3222 | """Standard database API wrapper.
|
|
0 commit comments