Skip to content

Instantly share code, notes, and snippets.

@thieman
Created June 13, 2025 22:14
Show Gist options
  • Save thieman/21908b175b37b61d50202f91408fef1a to your computer and use it in GitHub Desktop.
Save thieman/21908b175b37b61d50202f91408fef1a to your computer and use it in GitHub Desktop.
Plex cron causing resource leak
#!/etc/py3/bin/python
import argparse
from collections import Counter
import json
from datadog import initialize, statsd
from plexapi.server import PlexServer
import requests
initialize(**{
'statsd_socket_path': '/var/run/datadog/dsd.socket',
})
def set_plex_trmnl_visibility(visible):
plugin_id = None
items = requests.get(f"{TRMNL_HOST}/playlists/items", headers={'Authorization': f'Bearer {TRMNL_KEY}'}).json()
for item in items.get('data', []):
if item.get('plugin_setting', {}).get('name') == 'Plex':
plugin_id = item.get('id')
break
if not plugin_id:
raise ValueError("Plex TRMNL plugin not found")
requests.patch(f"{TRMNL_HOST}/playlists/items/{plugin_id}",
headers={
'Authorization': f'Bearer {TRMNL_KEY}',
'Content-Type': 'application/json',
},
data=json.dumps({'visible': visible})).raise_for_status()
def main():
parser = argparse.ArgumentParser(description='Plex stats')
parser.add_argument('stats', type=str, help='which stats to collect')
args = parser.parse_args()
plex = PlexServer(HOST, TOKEN)
if args.stats in ['all', 'session']:
emit_session_stats(plex)
if args.stats in ['all', 'media']:
emit_media_stats(plex)
def emit_session_stats(plex):
audio, video = 0, 0
if not plex.sessions():
statsd.gauge('plex.session', 0)
set_plex_trmnl_visibility(False)
else:
set_plex_trmnl_visibility(True)
user_counter = Counter()
for session in plex.sessions():
for username in session.usernames:
user_counter[username] += 1
for transcode_session in session.transcodeSessions:
if transcode_session.videoDecision == 'transcode':
video += 1
if transcode_session.audioDecision == 'transcode':
audio += 1
for user, count in user_counter.items():
statsd.gauge('plex.session', count, tags=[f'user:{user}'])
statsd.gauge('plex.transcode.video', video)
statsd.gauge('plex.transcode.audio', audio)
def emit_media_stats(plex):
for section in plex.library.sections():
statsd.gauge('plex.library.count', len(section.all()), tags=[f'type:{section.type}'])
if section.type == 'movie':
for movie in section.all():
if len(movie.media) > 1:
statsd.gauge('plex.media.duplicate', 1, tags=['type:movie', f'title:{movie.title}'])
size = 0
for media in movie.media:
for part in media.parts:
size += part.size
statsd.gauge('plex.media.size', size, tags=[f'type:movie', f'title:{movie.title}'])
if section.type == 'show':
for show in section.all():
statsd.gauge('plex.show.episodes', len(show.episodes()), tags=[f'title:{show.title}'])
for episode in show.episodes():
if len(episode.media) > 1:
statsd.gauge('plex.media.duplicate', 1, tags=['type:show', f'title:{show.title}', f'episode:{episode.seasonEpisode}'])
size = 0
for media in episode.media:
for part in media.parts:
size += part.size
statsd.gauge('plex.media.size', size, tags=[f'type:show', f'title:{show.title}', f'episode:{episode.seasonEpisode}'])
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment