Sam & Max » admin http://sametmax.com Du code, du cul Sat, 07 Nov 2015 10:56:13 +0000 en-US hourly 1 http://wordpress.org/?v=4.1 Accélérer les listings de l’admin Django avec beaucoup de ForeignKeys 3 http://sametmax.com/accelerer-les-listings-de-ladmin-django-avec-beaucoup-de-foreignkeys/ http://sametmax.com/accelerer-les-listings-de-ladmin-django-avec-beaucoup-de-foreignkeys/#comments Sun, 28 Sep 2014 07:32:29 +0000 http://sametmax.com/?p=12251 Je pensais que ces astuces étaient très connues, mais quand j’en ai eu besoin, j’ai galéré pour mettre la main dessus. Du coup blogage, blogation, blogitude.

L’admin Django permet de faire automatiquement un listing des objets voulus afin de les modifier. Si un modèle a une ForeignKey et qu’on définit le champ en list_editable, Django va pondre un drop down pour choisir parmi les relations possibles.

Or, le framework fait une requête pour chaque objet de la liste. Si vous avez deux ForeignKeys sur votre modèle et 20 objets (valeur par défaut) dans la liste, ça vous fait donc 40 queries, juste pour afficher ces deux drop down. Doh.

On peut néanmoins forcer Django à cacher le résultat de la première requête, réduisant ainsi le compte à 1, avec cette étrange astuce d’une mère au foyer (consultants hate her !) :

class VotreClasseAdmin(admin.ModelAdmin)
 
    # Cette méthode est appelée pour créer le champ de formulaire de pour
    # chaque objet
    def formfield_for_dbfield(self, db_field, **kwargs):
 
        request = kwargs['request']
        formfield = super(ProductPageAdmin, self).formfield_for_dbfield(db_field, **kwargs)
 
        # Si le champ est editable dans la liste
        if db_field.name in self.list_editable and hasattr(formfield, 'choices'):
 
            # On tente de récupérer la query en cache
            cache_attr_name = '_%s_cache' % db_field.name
            choices_cache = getattr(request, cache_attr_name)
            if choices_cache is not None:
                formfield.choices = choices_cache
 
            # Pas de cache, on force Django à faire la query en accédant
            # au descripteur .choices et on met le resultat
            # en cache
            else:
                setattr(request, cache_attr_name, formfield.choices)
 
        # On retourne le champ de notre formulaire avec sa valeur mise
        # en cache
        return formfield

Malheureusement, il peut arriver qu’il y ait tellement d’objets que c’est votre navigateur qui panique. En effet, si vous avez un modèle Promotion avec un lien vers un modèle Produit et que vous avez 5000 produits en base, vous allez créer 20 <select> avec 5000 <options> dedans. 100000 balises dans une page, ça peut faire mal.

Dans ce cas, il vaut mieux désactiver la possibilité de faire un drop down, et mettre un champ text à la place dans lequel on entre un ID en utilisant :

class VotreClasseAdmin(admin.ModelAdmin)
 
     raw_id_fields = ('nom_de_votre_champ',)

Django n’est pas chien, et vous mettra un petit bouton en forme de loupe pour chercher l’ID dont vous avez besoin.

Si vous avez beaucoup de ForeignKey non éditables (readonly_fields), vous pouvez aussi vous fendre d’un select_related :

class VotreClasseAdmin(admin.ModelAdmin)
 
    def queryset(self, request):
        # On filtre le queryset que Django va utiliser pour populer la liste
        return super(MyAdmin, self).queryset(request).select_related('myfield')

Ça ne marche que sur les non éditables, car pour eux Django ne créé pas de champ de formulaire.

]]>
http://sametmax.com/accelerer-les-listings-de-ladmin-django-avec-beaucoup-de-foreignkeys/feed/ 3
Monitorez vos serveurs avec munin et notifications par email 19 http://sametmax.com/monitorez-vos-serveurs-avec-munin-et-notifications-par-email/ http://sametmax.com/monitorez-vos-serveurs-avec-munin-et-notifications-par-email/#comments Wed, 24 Apr 2013 06:02:07 +0000 http://sametmax.com/?p=5860 Avoir un serveur c’est bien, en prendre soin c’est mieux. J’ai longtemps administré des serveurs sans trop me soucier de ce qui pouvait leur arriver et bien des fois tout a planté car je n’avais pas su anticiper la catastrophe.
Un exemple courant, j’ai viré Apache pour installer Nginx et ce dernier log par défaut les accès http, après quelques semaines, le disque dur bien rempli, le serveur me claque dans les doigts, plus de place, tout merde, c’est le drame, pas moyen de rebooter à part en safe mode car disque plein, les hémorroïdes s’en mêlent, c’est foutu.

J’ai commencé par MRTG, pas terrible à installer mais il fait son boulot. Et puis j’ai changé de serveur pas mal de fois en une année, horrible d’avoir à réinstaller ce truc à chaque fois alors j’ai cherché autre chose, après quelques tests pas terribles je suis tombé sur munin, plutôt complet avec des plugins que l’on peut écrire soit-même. Facile à installer quand on utilise les packages, suivez le guide.

Installation de Munin:
Munin se compose de deux programmes.
Le maître (munin): qui va récupérer les infos et générer les graphs.
Le noeud (munin-node): qui s’installe sur tous les serveurs à monitorer y compris le maître si besoin et qui va envoyer les infos au maître.

Sur le serveur Maître pour une distribution Ubuntu:

sudo apt-get install munin munin-node munin-plugins-extra
sudo ln -s /var/cache/munin/www /var/www/munin
sudo /etc/init.d/munin-node restart

Pour voir s’afficher les pages il vous faudra un serveur web, exemple avec Nginx:
dans le répertoire conf.d de Nginx ajoutez un fichier munin.conf et mettez-y le code suivant.

vi /usr/local/nginx/conf.d/munin.conf
server {
 
    listen       80;
    server_name munin.monserveur.com;
 
	location / {
	        auth_basic            "Restricted";
	        # Create the htpasswd file with the htpasswd tool.
	        auth_basic_user_file  /etc/nginx/htpasswd;
 
	        root /var/www/munin/;
	        index  index.html index.htm;
	        expires modified +310s;
	}
}

Note: vous pouvez désactiver l’authentification si vous voulez rendre votre page publique.

Après réglage de vos DNS chez votre registrar vous devriez avoir quelque chose à la page http://munin.monserveur.com

Sur les serveurs à monitorer (les noeuds):

sudo apt-get install munin-node munin-plugins-extra

Il faut maintenant “dire” au serveur noeud l’IP du serveur maître pour qu’il puisse lui envoyer les informations sur l’état de la machine.

Editez le fichier /etc/munin/munin-node.conf

allow ^192\.168\.1\.200$

Cette partie va permettre au Maître de venir récupérer les infos nécessaires. Remplacez l’IP par celle de votre serveur Maître.

On redémarre munin-node pour prendre en compte les changements.

sudo /etc/init.d/munin-node restart

PS: Si il ne se passe rien vérifiez que vous n’avez pas un firewall qui bloque l’IP et/ou le port TCP/4949

Les plugins:
Les plugins sont des petits programmes permettant de rajouter des fonctionnalitées au monitoring comme la supervision de services tels que Redis, Varnish, Nginx, etc. La liste est ici

Attention: L’ajout des plugins se fait côté serveur Noeud !

En fait il s’agit de simples liens symboliques dans le répertoire /etc/munin/plugins/ pointants vers le répertoire /usr/share/munin/plugins/.
La liste des plugins disponibles s’obtient avec:

sudo munin-node-configure

Exemple rajouter le plugin pour monitorer Mysql:

ln -s /usr/share/munin/plugins/mysql_queries /etc/munin/plugins/mysql_queries

Mysql en train de mourir...

Après que les machines noeuds aient été configurées on les déclare au serveur Maître:
Il faut éditer le fichier munin.conf sur le serveur Maître.

vi  /etc/munin/munin.conf
[sametmax]
    address sametmax.com
    df._home.warning 95
    use_node_name yes
 
[machine_locale_maitre]
    address  127.0.0.1
    use_node_name yes
 
[groupe_de_serveurs;]
    address  127.0.0.1
    use_node_name yes
 
[groupe_de_serveurs;serveur_adolf]
    address  33.94.124.33
    use_node_name yes
 
[groupe_de_serveurs;serveur_himler]
    address  33.94.124.33
    use_node_name yes
 
[groupe_de_serveurs;serveur_DSK]
    address  69.69.69.69
    use_node_name yes

Analysons la config ci-dessus:

sametmax:
Le premier va nous sortir les stats du serveur sametmax.com, on peut mettre l’ip comme le nom de domaine.

machine_locale_maitre:
Si on veut monitorer la machine maitre on met 127.0.0.1

groupe_de_serveurs:
Va définir un groupe de serveurs, l’affichage groupera tous les serveurs y appartenant, c’est juste pour un affichage plus clair, ne pas oublier le “;” à la fin

groupe_de_serveurs;serveur_adolf:
Un serveur qui apparaîtra dans le groupe de serveurs avec himler et DSK

Notification par email:
Avec munin il est possible de recevoir des notifications lorsque certains capteurs de votre monitoring atteignent un certain seuil.

Vérifiez bien que sendmail est installé et qu’il fonctionne
Dans le shell on teste sendmail

echo 'Promo sur les BBW' | mail -s 'sujet à poil les putes' monmail@moi.com

Toujours dans le fichier munin.conf sur le serveur Maître:

#email notifications settings
contacts max
contact.max.command mail -s "Munin notif ${var:host}" monmail@moi.com
contact.max.always_send warning critical

La premiere ligne définit un contact, la deuxième va envoyer l’email de notification via sendmail au mail indiqué.
La dernière ligne va indiquer à munin qu’il faut envoyer les alertes pour les warning et les critical.

Les seuils pour les notifications sont définis par warning et critical. Regardez plus haut pour le serveur [sametmax] nous avons défini un seuil pour df (disk free) de 95%.

[sametmax]
    address sametmax.com
    df._home.warning 95
    use_node_name yes

Ce qui veut dire que lorsque l’usage disque de /home aura dépassé les 95% d’utilisation munin va vous envoyer une notification par email. ça peut devenir lourd à la longue par contre car il s’arrête jamais :)

On redémarre munin sur le serveur maître pour prendre en compte les modif:

su - munin --shell=/bin/bash
/usr/share/munin/munin-update

Bon monitorage!

]]>
http://sametmax.com/monitorez-vos-serveurs-avec-munin-et-notifications-par-email/feed/ 19
Réinitialiser le mot de passe de l’admin django 1 http://sametmax.com/reinitialiser-le-mot-de-passe-de-ladmin-django/ http://sametmax.com/reinitialiser-le-mot-de-passe-de-ladmin-django/#comments Fri, 13 Apr 2012 23:21:56 +0000 http://sametmax.com/?p=388 Zut j’ai paumé le mot de passe de mon admin django. Bien évidement je ne l’ai pas sauvegarder la dernière fois pensant que je m’en rappellerais et surtout par pure fainéantise…

Pour réinitialiser un mot de passe on se connecte au shell et on import le User.

./manage.py shell
from django.contrib.auth.models import User
u = User.objects.get(username='admin')
u.set_password('nouveau_mot_de_passe')
u.save()

Et on a un nouveau mot de passe. Ouf! on peut retourner regarder une série tv pour fêter ça…

]]>
http://sametmax.com/reinitialiser-le-mot-de-passe-de-ladmin-django/feed/ 1