\n\n\n\n Guide des opérations de bot : Surveillance, mise à l'échelle et fiabilité - BotClaw Guide des opérations de bot : Surveillance, mise à l'échelle et fiabilité - BotClaw \n

Guide des opérations de bot : Surveillance, mise à l’échelle et fiabilité

📖 21 min read4,047 wordsUpdated Mar 27, 2026






Guide des opérations des bots : Surveillance, Mise à l’échelle et Fiabilité


Guide des opérations des bots : Surveillance, Mise à l’échelle et Fiabilité

Les bots sont devenus des éléments essentiels des applications modernes, automatisant des tâches, améliorant les interactions avec les utilisateurs et rationalisant les processus dans divers secteurs. Des chatbots de service client aux scripts d’automatisation back-end en passant par des agents IA sophistiqués, leur bon fonctionnement est crucial pour la continuité des affaires et la satisfaction des utilisateurs. Cependant, déployer un bot ne suffit pas. Pour libérer pleinement leur potentiel et s’assurer qu’ils apportent une valeur constante, une stratégie opérationnelle solide est indispensable. Cela signifie surveiller proactivement leur état, comprendre comment les mettre à l’échelle efficacement et établir des pratiques qui garantissent leur fiabilité.

Ce guide des opérations des bots fournit un cadre de base pour gérer des bots fiables en production. Nous allons explorer les piliers essentiels de la surveillance, de l’alerte, de la mise à l’échelle et de la réponse aux incidents, offrant des insights pratiques et des stratégies exploitables pour maintenir les performances des bots, prévenir les pannes et assurer une expérience fluide pour vos utilisateurs et systèmes. Que vous gériez un seul bot ou une flotte complexe, les principes exposés ici vous aideront à construire et maintenir une infrastructure bot résiliente.

1. Introduction aux Opérations des Bots

Les opérations des bots englobent la gestion complète du cycle de vie des agents automatisés une fois qu’ils sont déployés dans un environnement de production. Il s’agit de garantir que ces systèmes automatisés fonctionnent comme prévu, répondent aux exigences de performance et restent disponibles pour remplir leur objectif sans interruption. Cette discipline s’inspire largement des principes de l’Ingénierie de la Fiabilité des Sites (SRE), les adaptant spécifiquement aux caractéristiques uniques des bots.

Les objectifs principaux d’opérations des bots efficaces sont :

  • Disponibilité : S’assurer que les bots sont toujours accessibles et réactifs lorsque nécessaire.
  • Performance : Maintenir une vitesse et une efficacité optimales dans le traitement des demandes et l’exécution des tâches.
  • Précision : Vérifier que les bots exécutent correctement leurs fonctions et fournissent des résultats précis.
  • Scalabilité : La capacité à gérer une augmentation de la charge et de la demande sans dégradation de la performance.
  • Résilience : La capacité à se rétablir gracieusement après des pannes et des conditions imprévues.
  • Rentabilité : Optimiser l’utilisation des ressources pour minimiser les frais opérationnels.

Ignorer les opérations des bots peut entraîner des problèmes significatifs : des utilisateurs frustrés rencontrant des bots non réactifs ou incorrects, des opportunités d’affaires manquées en raison d’échecs d’automatisation, et une augmentation de l’intervention manuelle pour résoudre des problèmes, conduisant finalement à une perte de confiance dans vos systèmes automatisés. Une approche proactive, axée sur l’observation continue et l’amélioration, est primordiale.

Considérez un bot de support client. S’il se déconnecte fréquemment, donne des réponses incorrectes ou met trop de temps à répondre, les clients l’abandonneront rapidement et chercheront de l’aide humaine, contredisant l’objectif de l’automatisation. De même, un bot d’automatisation de processus interne qui échoue sans bruit peut entraîner des incohérences de données ou des retards dans des workflows critiques. Ce guide fournira les outils et la compréhension pour prévenir de tels scénarios et construire un cadre opérationnel solide pour tout bot.

[LIEN : Introduction aux Principes SRE]

2. Établir une Surveillance Efficace pour les Bots

La surveillance est la pierre angulaire des opérations fiables des bots. Elle fournit la visibilité nécessaire pour comprendre la santé, la performance et le comportement d’un bot en temps réel. Sans une surveillance solide, vous opérez dans l’ombre, incapables de détecter les problèmes avant qu’ils n’escaladent en problèmes critiques ou ne soient signalés par les utilisateurs.

Métriques Clés à Surveiller pour les Bots :

  • Disponibilité/Taux de Disponibilité : Le bot fonctionne-t-il ? Peut-il se connecter à ses dépendances ? Ceci est souvent mesuré par des vérifications de ping simples ou des transactions synthétiques.
  • Latence/Temps de Réponse : Le bot répond-il rapidement aux demandes ou exécute-t-il les tâches rapidement ? Une latence élevée peut indiquer des goulets d’étranglement de performance.
  • Taux d’Erreur : Le pourcentage de demandes ou de tâches qui entraînent une erreur. Cela peut être des erreurs HTTP (par exemple, 5xx), des erreurs spécifiques à l’application ou des échecs d’exécution de tâches.
  • Débit/Volume des Demandes : Le nombre de demandes traitées ou de tâches complétées par unité de temps. Utile pour comprendre la charge et la capacité.
  • Utilisation des Ressources : Utilisation CPU, mémoire, I/O réseau et utilisation du disque de l’hôte ou du conteneur du bot. Aide à identifier les contraintes de ressources.
  • Métriques Spécifiques à l’Application : Ce sont des métriques personnalisées cruciales pour le fonctionnement de votre bot. Exemple incluent :
    • Nombre d’appels API réussis par rapport aux échoués vers des services externes.
    • Nombre de messages traités (pour les bots de messagerie).
    • Scores d’analyse de sentiment (pour les bots conversationnels).
    • Nombre d’éléments traités dans une file d’attente.
    • Temps passé dans des phases de traitement spécifiques.
  • État des Dépendances : Statut des bases de données, des API externes, des files de messages et d’autres services sur lesquels votre bot repose.

Outils et Techniques pour la Surveillance des Bots :

Les solutions de surveillance modernes offrent une large gamme de capacités. Les choix populaires incluent :

  • Prometheus & Grafana : Une puissante combinaison open-source pour collecter des métriques de séries temporelles et les visualiser via des tableaux de bord. Les bots peuvent exposer des métriques via un point de terminaison HTTP.
  • Datadog, New Relic, Splunk : Solutions commerciales offrant une observabilité approfondie, y compris des métriques, des journaux et des traces, souvent avec une intégration facile et des alertes avancées.
  • Surveillance des Fournisseurs Cloud (AWS CloudWatch, Azure Monitor, Google Cloud Monitoring) : Services natifs pour surveiller les ressources et les applications déployées dans leurs environnements cloud respectifs.
  • Systèmes de Gestion des Journaux (ELK Stack – Elasticsearch, Logstash, Kibana ; Loki) : Essentiels pour collecter, centraliser et analyser les journaux des bots afin de diagnostiquer des problèmes et comprendre les patterns de comportement.

Exemple : Exposer des Métriques avec la Bibliothèque Client Prometheus (Python)


from prometheus_client import start_http_server, Counter, Gauge, Histogram
import time
import random

# Créer des métriques
REQUESTS_TOTAL = Counter('bot_requests_total', 'Nombre total de requêtes du bot.')
REQUEST_LATENCY = Histogram('bot_request_latency_seconds', 'Latence des requêtes du bot en secondes.')
CURRENT_ACTIVE_USERS = Gauge('bot_active_users', 'Nombre actuel d\'utilisateurs actifs du bot.')

def process_request():
 REQUESTS_TOTAL.inc()
 start_time = time.time()
 # Simuler un peu de travail
 time.sleep(random.uniform(0.1, 0.5))
 REQUEST_LATENCY.observe(time.time() - start_time)
 CURRENT_ACTIVE_USERS.set(random.randint(1, 100)) # Exemple de jauge dynamique

if __name__ == '__main__':
 # Démarrer le serveur pour exposer les métriques.
 start_http_server(8000)
 print("Métriques Prometheus exposées sur le port 8000")
 
 # Générer un trafic artificiel
 while True:
 process_request()
 time.sleep(0.1)
 

Ce snippet démontre comment un bot Python peut exposer des métriques que Prometheus peut récupérer et visualiser dans Grafana. Les tableaux de bord construits à partir de ces métriques offrent une vue opérationnelle en temps réel, vous permettant de repérer rapidement les tendances, les anomalies et les problèmes potentiels.

[LIÉ : Création de Tableaux de Bord de Surveillance Efficaces]

3. Stratégies d’Alerte : Répondre aux Anomalies

La surveillance vous indique ce qui se passe ; l’alerte vous informe quand quelque chose ne va pas et nécessite une attention. Une stratégie d’alerte efficace est cruciale pour minimiser les temps d’arrêt et atténuer l’impact des incidents. L’objectif est d’être informé des problèmes critiques rapidement sans subir la fatigue d’alerte.

Principes de l’Alerte Efficace :

  • Alerte Actionnable : Chaque alerte devrait idéalement indiquer un problème nécessitant une intervention humaine ou une remédiation automatisée. Évitez les alertes qui se contentent d’indiquer une condition sans implications claires.
  • Niveaux de Sévérité : Catégorisez les alertes par leur urgence et impact (ex. : Critique, Avertissement, Informatif). Cela aide à prioriser les réponses.
  • Contexte Clair : Les alertes devraient fournir suffisamment d’informations pour comprendre le problème d’un coup d’œil : quel bot est affecté, quelle métrique a déclenché l’alerte, valeur actuelle, seuils, et liens vers des tableaux de bord ou des journaux pertinents.
  • Canaux Appropriés : Livrez les alertes via des canaux adaptés à leur sévérité. Les alertes critiques pourraient être envoyées aux pagers de garde (ex. : PagerDuty, Opsgenie), tandis que les avertissements pourraient aller vers des canaux Slack ou par email.
  • Debouncing/Aggregation : Empêchez une seule cause profonde de générer un flot d’alertes redondantes. Agrégez des alertes similaires ou utilisez un debouncing intelligent.
  • Runbooks : Liez les alertes à des runbooks—des procédures documentées pour enquêter et résoudre des problèmes courants.

Scénarios d’Alerte Courants pour les Bots :

  • Taux d’Erreur Élevé : Déclenchez lorsque le taux d’erreur d’un bot dépasse un seuil prédéfini (ex. : 5 % d’erreurs sur 5 minutes).
  • Latence Accrue : Alertez si le temps de réponse moyen dépasse une limite acceptable (ex. : P95 latence > 2 secondes).
  • Bot Non Réactif/Hors Service : Alerte critique si le point de contrôle de santé du bot échoue ou si aucune métrique n’est rapportée.
  • Saturation des Ressources : Avertissement si l’utilisation du CPU ou de la mémoire dépasse constamment un pourcentage élevé (ex. : >80 %).
  • Arriéré de File d’Attente : Pour les bots traitant des files d’attente, alertez si la taille de la file d’attente dépasse un certain seuil, indiquant un goulet d’étranglement de traitement.
  • Échec de Dépendance : Alertez si une API externe sur laquelle le bot compte devient indisponible ou retourne trop d’erreurs.
  • Échec de Logique Métier : Alertes personnalisées basées sur des métriques spécifiques à l’application, telles qu’une chute soudaine des transactions réussies ou un changement inattendu de sortie.

Exemple : Règle d’Alerte Prometheus (YAML)


groups:
- name: bot-alerts
 rules:
 - alert: BotHighErrorRate
 expr: sum(rate(bot_requests_total{status="error"}[5m])) by (instance) / sum(rate(bot_requests_total[5m])) by (instance) > 0.1
 for: 5m
 labels:
 severity: critical
 annotations:
 summary: "L'instance de bot {{ $labels.instance }} a un taux d'erreur élevé"
 description: "Le taux d'erreur pour le bot {{ $labels.instance }} est supérieur à 10% pendant 5 minutes. Taux actuel : {{ $value | humanizePercentage }}"
 runbook_url: "https://your-docs.com/runbooks/bot-error-rate"
 
 - alert: BotUnresponsive
 expr: absent(up{job="my-bot"})
 for: 2m
 labels:
 severity: critical
 annotations:
 summary: "Mon Bot est hors service"
 description: "Le travail 'my-bot' ne rapporte pas de statut 'up'. Il pourrait être hors service ou inaccessible."
 

Ces règles, configurées dans Alertmanager, déclencheraient des notifications lorsque les conditions spécifiées sont remplies. La clause for garantit que la condition persiste pendant une durée avant de se déclencher, réduisant les alertes oscillantes. L’intégration avec un service comme PagerDuty garantit que les alertes critiques atteignent l’équipe de garde.

[LIÉ : Conception des Rotations de Garde]

4. Mise à l’Échelle de Vos Bots pour La Performance et La Croissance

À mesure que votre base d’utilisateurs croît ou que les demandes sur vos bots augmentent, leur capacité à s’adapter devient primordiale. La mise à l’échelle garantit que vos bots peuvent gérer une charge accrue sans dégradation des performances, maintenant une expérience utilisateur cohérente et fiable. Il existe deux principales approches pour la mise à l’échelle : verticale et horizontale.

Mise à l’Échelle Verticale (Scaling Up) :

Cela implique d’augmenter les ressources (CPU, RAM, disque I/O) d’une seule instance de bot. C’est souvent le premier pas le plus simple à la mise à l’échelle. Cependant, il existe des limites physiques quant à la quantité que vous pouvez augmenter une seule machine, et cela introduit un point de défaillance unique. C’est adapté aux applications qui sont par nature difficiles à distribuer ou qui ont des tâches spécifiques gourmandes en ressources.

Mise à l’Échelle Horizontale (Scaling Out) :

Cela implique d’ajouter plus d’instances de votre bot, répartissant la charge sur plusieurs machines ou conteneurs. C’est généralement la méthode préférée pour les architectures de bot modernes et natives du cloud car elle offre une plus grande résilience, élasticité, et rentabilité. Les principales considérations pour la mise à l’échelle horizontale incluent :

  • Statelessness : Concevez vos bots pour qu’ils soient aussi sans état que possible. Cela signifie qu’aucune instance du bot ne peut traiter n’importe quelle demande, et aucune donnée de session utilisateur n’est stockée localement dans l’instance du bot. Si un état est nécessaire, externalisez-le vers un magasin de données partagé et hautement disponible (ex. : Redis, une base de données).
  • Équilibrage de Charge : Un équilibreur de charge distribue les demandes entrantes sur les instances de bot disponibles, garantissant qu’aucune instance unique n’est surchargée. Les plateformes cloud modernes fournissent des équilibreurs de charge gérés (ex. : AWS ELB, Azure Load Balancer, GCP Load Balancing).
  • Mise à l’Échelle Automatique : Ajustez automatiquement le nombre d’instances de bot en fonction des métriques en temps réel (utilisation du CPU, longueur de la file d’attente des demandes, métriques d’application personnalisées). Cela garantit que les ressources sont provisionnées uniquement lorsque nécessaire, optimisant ainsi les coûts et les performances.
  • Conteneurisation : Des technologies comme Docker et des plateformes d’orchestration de conteneurs comme Kubernetes sont idéales pour la mise à l’échelle horizontale. Elles regroupent votre bot et ses dépendances en unités portables, rendant le déploiement et la mise à l’échelle de plusieurs instances simples.

Exemple : Mise à l’Échelle Automatique d’un Bot avec Kubernetes (HPA)

Un Horizontal Pod Autoscaler (HPA) dans Kubernetes peut automatiquement mettre à l’échelle le nombre de pods de bot en fonction de l’utilisation CPU ou de métriques personnalisées.


apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
 name: my-bot-hpa
spec:
 scaleTargetRef:
 apiVersion: apps/v1
 kind: Deployment
 name: my-bot-deployment
 minReplicas: 2
 maxReplicas: 10
 metrics:
 - type: Resource
 resource:
 name: cpu
 target:
 type: Utilization
 averageUtilization: 70
 # Vous pouvez également mettre à l'échelle en fonction de métriques personnalisées, ex. : longueur de la file d'attente
 # - type: Pods
 # pods:
 # metric:
 # name: bot_queue_length
 # target:
 # type: AverageValue
 # averageValue: 50
 

Cette configuration HPA garantira que le my-bot-deployment a toujours entre 2 et 10 répliques. Si l’utilisation moyenne du CPU à travers tous les pods dépasse 70 %, Kubernetes ajoutera plus de pods, jusqu’à la limite maximum. Si l’utilisation diminue, il met à l’échelle vers le bas. Cette élasticité est cruciale pour gérer une demande fluctuante.

Lors de la conception pour la mise à l’échelle, envisagez également l’évolutivité de vos dépendances. Un bot hautement évolutif sera toujours limité si sa base de données ou ses API externes ne le sont pas. Les tests de charge et l’évaluation des performances sont des étapes vitales pour identifier les goulets d’étranglement avant qu’ils n’impactent la production.

[LIÉ : Conception de Bots pour Environnements Cloud]

5. Assurer la Fiabilité et la Résilience des Bots

La fiabilité est la probabilité qu’un bot exécute sa fonction prévue sans échec pendant une période spécifiée dans des conditions données. La résilience est la capacité d’un bot à se remettre rapidement des échecs et à continuer à fonctionner. Atteindre une haute fiabilité et résilience nécessite une approche multifacette, intégrant des pratiques tout au long du cycle de vie du bot.

Stratégies Clés pour la Fiabilité :

  • Redondance : Évitez les points de défaillance uniques. Déployez plusieurs instances de votre bot (comme discuté dans la mise à l’échelle) et assurez-vous que les dépendances critiques ont également une redondance (par exemple, bases de données répliquées, plusieurs points de terminaison API).
  • Tolérance aux pannes : Concevez votre bot pour gérer gracieusement les erreurs provenant des dépendances ou des entrées inattendues. Mettez en œuvre une gestion solide des erreurs, des réessais avec un temps d’attente exponentiel et des disjoncteurs.
  • Idempotence : Concevez des opérations pour être idempotentes, ce qui signifie que l’exécution de la même opération plusieurs fois a le même effet que de l’exécuter une seule fois. Cela est crucial pour les mécanismes de réessai et prévient les effets secondaires indésirables.
  • Vérifications de santé : Mettez en œuvre des points de terminaison de vérification de santé dédiés que les systèmes de surveillance peuvent interroger pour déterminer si le bot est opérationnel et en bonne santé. Ceux-ci peuvent être de simples réponses HTTP 200 ou des vérifications plus complexes qui vérifient les connexions aux bases de données, la connectivité API, etc.
  • Validation des entrées : Validez rigoureusement toutes les entrées pour éviter les comportements inattendus, les vulnérabilités de sécurité et les pannes causées par des données malformées.
  • Limitation de taux & Régulation : Protégez votre bot et ses dépendances d’une charge excessive en mettant en œuvre une limitation de taux sur les requêtes entrantes et en respectant les limites de taux des API externes.
  • Observabilité : Comme discuté, une surveillance, une journalisation et un traçage approfondis sont fondamentaux pour comprendre le comportement du bot et diagnostiquer rapidement les problèmes.
  • Gestion de la configuration : Externalisez la configuration du code. Utilisez des variables d’environnement ou des services de gestion de configuration (par exemple, Consul, AWS Systems Manager Parameter Store) pour gérer les paramètres, rendant les déploiements cohérents et empêchant le codage en dur d’informations sensibles.

Exemple : Mise en œuvre d’un disjoncteur (Python avec Tenacity)


from tenacity import retry, stop_after_attempt, wait_fixed, circuit_breaker, retry_if_exception_type
import requests

# Définir une exception personnalisée pour le disjoncteur
class ExternalServiceFailure(Exception):
 pass

# Configurer le disjoncteur
# Si 3 appels consécutifs échouent, ouvrir le circuit pendant 60 secondes
@retry(
 stop=stop_after_attempt(3),
 wait=wait_fixed(2),
 retry=retry_if_exception_type(requests.exceptions.RequestException),
 after=circuit_breaker(3, 60, reraise=True, on_break=lambda *args: print("Disjoncteur OUVERT !"), on_recover=lambda *args: print("Disjoncteur FERMÉ !"))
)
def call_external_api(url):
 print(f"Tentative d'appel à {url}...")
 response = requests.get(url, timeout=5)
 response.raise_for_status() # Lève HTTPError pour les mauvaises réponses (4xx ou 5xx)
 print(f"Appel réussi à {url} : {response.status_code}")
 return response.json()

if __name__ == "__main__":
 # Simuler un service externe qui échoue parfois
 test_url = "http://bad-api.example.com/data" # Remplacer par une véritable URL échouante pour les tests
 for i in range(10):
 try:
 call_external_api(test_url)
 except requests.exceptions.RequestException as e:
 print(f"L'appel a échoué : {e}")
 except ExternalServiceFailure as e:
 print(f"Le disjoncteur a empêché l'appel : {e}")
 time.sleep(1)
 

Un modèle de disjoncteur empêche une dépendance défaillante de provoquer des défaillances en cascade dans votre système en stoppant temporairement les appels à cette dépendance une fois qu’elle atteint un certain seuil d’erreur. Cela permet au service externe de se rétablir et empêche votre bot de gaspiller des ressources sur des requêtes condamnées.

[LIÉ : Concevoir pour la fiabilité des microservices]

6. Réponse aux incidents et analyse post-mortem

Même avec les meilleures pratiques en matière de surveillance, de mise à l’échelle et de fiabilité, des incidents se produiront inévitablement. La façon dont vous répondez à ces incidents et apprenez d’eux est essentielle pour l’amélioration continue et le renforcement de la résilience.

Flux de réponse aux incidents :

  1. Détection : Une alerte se déclenche, ou un utilisateur signale un problème, indiquant qu’un bot ne fonctionne pas correctement.
  2. Triage : L’équipe de garde reconnait l’alerte, évalue la gravité et détermine l’impact potentiel.
  3. Investigation : En utilisant des tableaux de bord de surveillance, des journaux et un traçage, l’équipe identifie la cause profonde de l’incident. Cela peut impliquer de vérifier les déploiements récents, l’état des dépendances ou l’utilisation des ressources.
  4. Atténuation : Mettez en œuvre des actions immédiates pour réduire l’impact de l’incident. Cela pourrait impliquer de revenir à un déploiement précédent, de redémarrer une instance de bot, d’augmenter les ressources ou de désactiver temporairement une fonctionnalité. L’objectif est de rétablir le service aussi rapidement que possible, même s’il s’agit d’une solution temporaire.
  5. Résolution : Une fois que le bot est de nouveau en fonctionnement normal et que la menace immédiate est résolue, l’incident est clos.
  6. Communication : Tout au long de l’incident, communiquez de manière transparente avec les parties prenantes (équipes internes, utilisateurs si applicable) sur l’état et la résolution prévue.

Éléments clés d’une réponse aux incidents efficace :

  • Rotation d’appel : Un calendrier clairement défini pour qui est responsable de répondre aux alertes 24/7.
  • Canaux de communication : Canaux dédiés (par exemple, Slack, Microsoft Teams) pour la coordination des incidents.
  • Runbooks : Guides détaillés, étape par étape, pour les types d’incidents courants, permettant aux intervenants d’agir rapidement.
  • Plateforme de gestion des incidents : Outils comme PagerDuty, Opsgenie ou VictorOps aident à gérer les alertes, les horaires d’appel et la communication sur les incidents.

Analyse post-mortem (Analyse des causes profondes) :

Après qu’un incident soit résolu, une analyse post-mortem sans reproche est essentielle. Il ne s’agit pas d’attribuer des responsabilités mais de comprendre ce qui s’est passé, pourquoi cela s’est produit, et ce qui peut être fait pour prévenir une récurrence. Les composants clés d’une analyse post-mortem :

  • Chronologie des événements : Un compte rendu détaillé et chronologique de l’incident, de la détection à la résolution.
  • Évaluation de l’impact : Quantifiez l’impact sur les utilisateurs, les affaires et d’autres systèmes.
  • Analyse des causes profondes : Allez au-delà des symptômes de surface pour identifier les problèmes systémiques sous-jacents. Utilisez des techniques comme les « 5 Pourquoi ».
  • Leçons tirées : Qu’est-ce qui a bien fonctionné ? Qu’est-ce qui aurait pu être mieux ?
  • Actions à mener : Tâches concrètes, assignables pour traiter les causes profondes, améliorer la détection, renforcer les stratégies d’atténuation ou mettre à jour les runbooks. Celles-ci doivent être priorisées et suivies.

Exemple : Suivi des actions post-mortem

Action à mener Responsable

Articles connexes

🕒 Published:

🛠️
Written by Jake Chen

Full-stack developer specializing in bot frameworks and APIs. Open-source contributor with 2000+ GitHub stars.

Learn more →
Browse Topics: Bot Architecture | Business | Development | Open Source | Operations

See Also

ClawgoAgent101AgntkitClawdev
Scroll to Top