darshan-parser.c 7.82 KB
Newer Older
1
/*
2 3 4
 * Copyright (C) 2015 University of Chicago.
 * See COPYRIGHT notice in top-level directory.
 *
5 6
 */

7 8 9 10 11 12 13 14
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <zlib.h>
#include <time.h>
15
#include <stdlib.h>
16
#include <getopt.h>
17
#include <assert.h>
18

19
#include "uthash-1.9.2/src/uthash.h"
20

21
#include "darshan-logutils.h"
22

23 24 25
int main(int argc, char **argv)
{
    int ret;
26
    int i, j;
27
    char *filename;
28
    char tmp_string[4096] = {0};
29 30 31 32
    darshan_fd fd;
    struct darshan_header header;
    struct darshan_job job;
    struct darshan_record_ref *rec_hash = NULL;
33
    struct darshan_record_ref *ref, *tmp;
34 35 36
    int mount_count;
    char** mnt_pts;
    char** fs_types;
37
    time_t tmp_time = 0;
38 39
    char *token;
    char *save;
40
    char buffer[DARSHAN_JOB_METADATA_LEN];
41
    int empty_mods = 0;
42 43
    char *mod_buf;
    int mod_buf_sz;
44

45 46 47
    /* TODO: argument parsing */
    assert(argc == 2);
    filename = argv[1];
48

49 50
    fd = darshan_log_open(filename, "r");
    if(!fd)
51
    {
52
        fprintf(stderr, "darshan_log_open() failed to open %s\n.", filename);
53 54
        return(-1);
    }
55 56 57

    /* read darshan log header */
    ret = darshan_log_getheader(fd, &header);
58
    if(ret < 0)
59
    {
60 61
        fprintf(stderr, "darshan_log_getheader() failed to read log header.\n");
        darshan_log_close(fd);
62 63 64
        return(-1);
    }

65 66 67 68 69 70 71 72
    /* read darshan job info */
    ret = darshan_log_getjob(fd, &job);
    if(ret < 0)
    {
        fprintf(stderr, "darshan_log_getjob() failed to read job data.\n");
        darshan_log_close(fd);
        return(-1);
    }
73

74 75
    /* get the original command line for this job */
    ret = darshan_log_getexe(fd, tmp_string);
76
    if(ret < 0)
77
    {
78
        fprintf(stderr, "Error: unable to read trailing job information.\n");
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
        darshan_log_close(fd);
        return(-1);
    }

    /* get the mount information for this log */
    ret = darshan_log_getmounts(fd, &mnt_pts, &fs_types, &mount_count);
    if(ret < 0)
    {
        fprintf(stderr, "darshan_log_getmounts() failed to read mount information.\n");
        darshan_log_close(fd);
        return(-1);
    }

    /* read hash of darshan records */
    ret = darshan_log_gethash(fd, &rec_hash);
    if(ret < 0)
    {
        fprintf(stderr, "darshan_log_getmap() failed to read record map.\n");
        darshan_log_close(fd);
98 99 100
        return(-1);
    }

101
    /* print job summary */
102
    printf("# darshan log version: %s\n", header.version_string);
103
    printf("# exe: %s\n", tmp_string);
Philip Carns's avatar
Philip Carns committed
104 105 106
    printf("# uid: %" PRId64 "\n", job.uid);
    printf("# jobid: %" PRId64 "\n", job.jobid);
    printf("# start_time: %" PRId64 "\n", job.start_time);
107
    tmp_time += job.start_time;
108
    printf("# start_time_asci: %s", ctime(&tmp_time));
Philip Carns's avatar
Philip Carns committed
109
    printf("# end_time: %" PRId64 "\n", job.end_time);
110 111
    tmp_time = 0;
    tmp_time += job.end_time;
112
    printf("# end_time_asci: %s", ctime(&tmp_time));
Philip Carns's avatar
Philip Carns committed
113 114
    printf("# nprocs: %" PRId64 "\n", job.nprocs);
    printf("# run time: %" PRId64 "\n", job.end_time - job.start_time + 1);
115 116 117 118 119
    for(token=strtok_r(job.metadata, "\n", &save);
        token != NULL;
        token=strtok_r(NULL, "\n", &save))
    {
        char *key;
120 121 122 123 124 125 126 127 128 129 130 131 132 133
        char *value;
        /* NOTE: we intentionally only split on the first = character.
         * There may be additional = characters in the value portion
         * (for example, when storing mpi-io hints).
         */
        strcpy(buffer, token);
        key = buffer;
        value = index(buffer, '=');
        if(!value)
            continue;
        /* convert = to a null terminator to split key and value */
        value[0] = '\0';
        value++;
        printf("# metadata: %s = %s\n", key, value);
134
    }
135

136
    /* print breakdown of each log file component's contribution to file size */
137
    printf("\n# log file component sizes (compressed)\n");
138
    printf("# -------------------------------------------------------\n");
139 140
    printf("# header: %zu bytes (uncompressed)\n", sizeof(struct darshan_header));
    printf("# job data: %zu bytes\n", header.rec_map.off - sizeof(struct darshan_header));
141 142
    printf("# record table: %zu bytes\n", header.rec_map.len);
    for(i=0; i<DARSHAN_MAX_MODS; i++)
143
    {
144
        if(header.mod_map[i].len)
145
        {
146 147
            printf("# %s module: %zu bytes\n", darshan_module_names[i],
                header.mod_map[i].len);
148
        }
149 150
    }

151 152 153
    /* print table of mounted file systems */
    printf("\n# mounted file systems (mount point and fs type)\n");
    printf("# -------------------------------------------------------\n");
154 155
    for(i=0; i<mount_count; i++)
    {
156
        printf("# mount entry:\t%s\t%s\n", mnt_pts[i], fs_types[i]);
157
    }
158

159 160 161 162
    mod_buf = malloc(DARSHAN_DEF_COMP_BUF_SZ);
    if(!mod_buf)
        return(-1);

163
    DARSHAN_PRINT_HEADER();
164
    /* TODO: does each module print header of what each counter means??? */
165

166
    for(i=0; i<DARSHAN_MAX_MODS; i++)
167
    {
168 169
        int mod_bytes_left;
        void *mod_buf_p;
170 171
        void *rec_p = NULL;
        darshan_record_id rec_id;
172

173 174 175 176 177 178
        memset(mod_buf, 0, DARSHAN_DEF_COMP_BUF_SZ);
        mod_buf_sz = DARSHAN_DEF_COMP_BUF_SZ;

        /* check each module for any data */
        ret = darshan_log_getmod(fd, i, mod_buf, &mod_buf_sz);
        if(ret < 0)
179
        {
180 181 182 183 184 185 186 187 188
            fprintf(stderr, "Error: failed to get module %s data\n",
                darshan_module_names[i]);
            fflush(stderr);
            darshan_log_close(fd);
            return(-1);
        }
        else if(ret == 0)
        {
            /* skip modules not present in log file */
189 190
            empty_mods++;
            continue;
191 192
        }

193 194
        /* skip modules with no defined logutil handlers */
        if(!mod_logutils[i])
195
        {
196 197 198
            fprintf(stderr, "Warning: no log utility handlers defined "
                "for module %s, SKIPPING\n", darshan_module_names[i]);
            continue;
199 200
        }

201
        /* this module has data to be parsed and printed */
202 203
        mod_buf_p = mod_buf;
        mod_bytes_left = mod_buf_sz;
204

205
        /* loop over each of this module's records and print them */
206
        while (mod_bytes_left > 0)
207 208 209
        {
            char *mnt_pt = NULL;
            char *fs_type = NULL;
Philip Carns's avatar
Philip Carns committed
210

211 212 213 214 215 216 217 218 219 220 221
            ret = mod_logutils[i]->log_get_record(fd, &mod_buf_p, &mod_bytes_left,
                &rec_p, &rec_id);
            if(ret < 0)
            {
                fprintf(stderr, "Error: failed to parse module %s data record\n",
                    darshan_module_names[i]);
                fflush(stderr);
                darshan_log_close(fd);
                return(-1);
            }

222 223 224
            /* get the pathname for this record */
            HASH_FIND(hlink, rec_hash, &rec_id, sizeof(darshan_record_id), ref);
            assert(ref);
225

226 227
            /* get mount point and fs type associated with this record */
            for(j=0; j<mount_count; j++)
228
            {
229 230 231 232 233 234
                if(strncmp(mnt_pts[j], ref->rec.name, strlen(mnt_pts[j])) == 0)
                {
                    mnt_pt = mnt_pts[j];
                    fs_type = fs_types[j];
                    break;
                }
235
            }
236 237 238 239
            if(!mnt_pt)
                mnt_pt = "UNKNOWN";
            if(!fs_type)
                fs_type = "UNKNOWN";
240

241 242 243
            /* print the corresponding module data for this record */
            mod_logutils[i]->log_print_record(rec_p, ref->rec.name,
                mnt_pt, fs_type);
244
        }
245 246 247
    }
    if(empty_mods == DARSHAN_MAX_MODS)
        printf("# no module data available.\n");
248

249 250
    free(mod_buf);

251 252 253 254 255 256
    /* free record hash data */
    HASH_ITER(hlink, rec_hash, ref, tmp)
    {
        HASH_DELETE(hlink, rec_hash, ref);
        free(ref->rec.name);
        free(ref);
257 258
    }

259 260
    /* free mount info */
    for(i=0; i<mount_count; i++)
261
    {
262 263
        free(mnt_pts[i]);
        free(fs_types[i]);
264
    }
265
    if(mount_count > 0)
266
    {
267 268
        free(mnt_pts);
        free(fs_types);
269 270
    }

271
    darshan_log_close(fd);
272

273
    return(0);
274
}